specrails-desktop 2.57.0 → 2.58.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (336) hide show
  1. package/README.md +1 -1
  2. package/cli/dist/args.js +10 -4
  3. package/cli/dist/help.js +1 -1
  4. package/client/dist/assets/{ActivityFeedPage-DdMNmVBk.js → ActivityFeedPage-BQGppIR0.js} +1 -1
  5. package/client/dist/assets/{AgentBrowserCapture-CeerUf--.js → AgentBrowserCapture-PI-cxyxi.js} +1 -1
  6. package/client/dist/assets/{AgentModeAnalyticsPane-BjGb-8rh.js → AgentModeAnalyticsPane-mQsOqdXx.js} +2 -2
  7. package/client/dist/assets/{AgentModeCodePane-8XRkQEo_.js → AgentModeCodePane-BL-vpmlY.js} +2 -2
  8. package/client/dist/assets/{AgentModeJobsPane-BN3dgJOA.js → AgentModeJobsPane-DR_06oqH.js} +1 -1
  9. package/client/dist/assets/AgentsPage-BKIKjm_1.js +118 -0
  10. package/client/dist/assets/{AnalyticsPage-CyfhYiBn.js → AnalyticsPage-069npRVo.js} +1 -1
  11. package/client/dist/assets/{CodePage-C2Nf-Q5W.js → CodePage-Alitorrv.js} +2 -2
  12. package/client/dist/assets/DesktopAnalyticsPage-qtWAPM47.js +1 -0
  13. package/client/dist/assets/{DocsDialog-Br3bczCp.js → DocsDialog-DwL6rgcT.js} +1 -1
  14. package/client/dist/assets/{DocsPage-BcDr2cBm.js → DocsPage-BA1hiJZ-.js} +1 -1
  15. package/client/dist/assets/{ExportDropdown-BVGKEgkd.js → ExportDropdown-BcMpvV89.js} +1 -1
  16. package/client/dist/assets/InteractiveJobComposer-B3H1YHr6.js +19 -0
  17. package/client/dist/assets/JobDetailModal-XZQ9eAAy.js +1 -0
  18. package/client/dist/assets/{JobDetailPage-vBbNeRuz.js → JobDetailPage-B-SIaq_q.js} +1 -1
  19. package/client/dist/assets/{JobsPage-CJCtPhIz.js → JobsPage-iQXAv2mx.js} +1 -1
  20. package/client/dist/assets/LoopBuilderPage-B_gbFAHn.js +1 -0
  21. package/client/dist/assets/LoopPreviewModal-je5pSCf-.js +1 -0
  22. package/client/dist/assets/LoopsPage-BZwcY5cu.js +2 -0
  23. package/client/dist/assets/{MinimizedChatsContext-D3QzgV0B.js → MinimizedChatsContext-CNx_0bZu.js} +1 -1
  24. package/client/dist/assets/{PluginsPage-DOpTV75p.js → PluginsPage-DFocnoHX.js} +2 -2
  25. package/client/dist/assets/{ProjectSettingsDialog-Dkwrn0z1.js → ProjectSettingsDialog-Bh3S6EBB.js} +1 -1
  26. package/client/dist/assets/{RepositoryDeliveries-Du2UCf1a.js → RepositoryDeliveries-BiwJuS8r.js} +1 -1
  27. package/client/dist/assets/{RepositoryScopeSelector-hPGZNRBm.js → RepositoryScopeSelector-C2mvWBQ6.js} +1 -1
  28. package/client/dist/assets/{ReviewPacketPage-DcOq-UTA.js → ReviewPacketPage-CrAf-WDy.js} +2 -2
  29. package/client/dist/assets/TemplatePreviewModal-C7DordpN.js +1 -0
  30. package/client/dist/assets/{TicketDetailModalContext-DAK-NoK6.js → TicketDetailModalContext-B-DySpKL.js} +1 -1
  31. package/client/dist/assets/{Trans-DEbgkuAY.js → Trans-D3AfDylf.js} +1 -1
  32. package/client/dist/assets/agentRuntime-BeUb3g9g.js +1 -0
  33. package/client/dist/assets/agentRuntime-Bg9tbmqm.js +1 -0
  34. package/client/dist/assets/agentRuntime-D-GJVGkj.js +1 -0
  35. package/client/dist/assets/agentRuntime-D2__CVI_.js +1 -0
  36. package/client/dist/assets/agentRuntime-D35dGVOP.js +1 -0
  37. package/client/dist/assets/agentRuntime-DGz_IqKW.js +1 -0
  38. package/client/dist/assets/agentRuntime-O1liDt6G.js +1 -0
  39. package/client/dist/assets/agentRuntime-hInH9Fzj.js +1 -0
  40. package/client/dist/assets/agentstudio-B2CTtQgZ.js +1 -0
  41. package/client/dist/assets/agentstudio-BWAKeGgB.js +1 -0
  42. package/client/dist/assets/{agentstudio-DR7doNBV.js → agentstudio-Cja8Sjcp.js} +1 -1
  43. package/client/dist/assets/agentstudio-DtfPcr99.js +1 -0
  44. package/client/dist/assets/agentstudio-QdAJIDef.js +1 -0
  45. package/client/dist/assets/agentstudio-X70BKf6u.js +1 -0
  46. package/client/dist/assets/agentstudio-fLXpRGIi.js +1 -0
  47. package/client/dist/assets/agentstudio-qXKqVnWS.js +1 -0
  48. package/client/dist/assets/{analytics-jzCkOec3.js → analytics-B1DIQd4m.js} +1 -1
  49. package/client/dist/assets/{analytics-CoEzWPx4.js → analytics-BAIZ9vE_.js} +1 -1
  50. package/client/dist/assets/{analytics-DjLlE7jS.js → analytics-BTqgmgBd.js} +1 -1
  51. package/client/dist/assets/analytics-BWynXPEm.js +1 -0
  52. package/client/dist/assets/{analytics-nZIjjtCc.js → analytics-DGcUsQ44.js} +1 -1
  53. package/client/dist/assets/{analytics-BNgZ1Nj7.js → analytics-GnSnpJ4W.js} +1 -1
  54. package/client/dist/assets/{analytics-DFh5lSOl.js → analytics-TWgYaoO0.js} +1 -1
  55. package/client/dist/assets/{analytics-DZp-DS2U.js → analytics-kJy6Tuko.js} +1 -1
  56. package/client/dist/assets/builder-C0FyvM83.js +1 -0
  57. package/client/dist/assets/builder-C1neIYGR.js +1 -0
  58. package/client/dist/assets/builder-CvnFm0im.js +1 -0
  59. package/client/dist/assets/builder-CzW5ovyI.js +1 -0
  60. package/client/dist/assets/builder-D06L7iPy.js +1 -0
  61. package/client/dist/assets/builder-DGETbtZj.js +1 -0
  62. package/client/dist/assets/builder-DXEJUlC0.js +1 -0
  63. package/client/dist/assets/builder-DyQperXU.js +1 -0
  64. package/client/dist/assets/common-BCK7c9Pv.js +1 -0
  65. package/client/dist/assets/common-C0BOdeNi.js +1 -0
  66. package/client/dist/assets/common-C4Yvvhp6.js +1 -0
  67. package/client/dist/assets/{common-BrlwEnL7.js → common-DmsclwjP.js} +1 -1
  68. package/client/dist/assets/common-DpLWwgI1.js +1 -0
  69. package/client/dist/assets/common-OCvl3c8t.js +1 -0
  70. package/client/dist/assets/common-c0aujEZC.js +1 -0
  71. package/client/dist/assets/common-od8WThlf.js +1 -0
  72. package/client/dist/assets/dashboard-B1ndRHuC.js +1 -0
  73. package/client/dist/assets/dashboard-BX7KXiqA.js +1 -0
  74. package/client/dist/assets/dashboard-B_BSNxcN.js +1 -0
  75. package/client/dist/assets/dashboard-CCeFN7-V.js +1 -0
  76. package/client/dist/assets/dashboard-CRl0WtFJ.js +1 -0
  77. package/client/dist/assets/dashboard-XGdQ5mjw.js +1 -0
  78. package/client/dist/assets/dashboard-_oltA6Jd.js +1 -0
  79. package/client/dist/assets/dashboard-bAuf5KVk.js +1 -0
  80. package/client/dist/assets/{formatDistanceToNow-Cc2u5FwQ.js → formatDistanceToNow-aBss1Nai.js} +1 -1
  81. package/client/dist/assets/{getTimezoneOffsetInMilliseconds-BHm2U-w1.js → getTimezoneOffsetInMilliseconds-DOGj1Mfz.js} +1 -1
  82. package/client/dist/assets/index-BS7KCWkV.css +2 -0
  83. package/client/dist/assets/{index-Cxb288Rj.js → index-C4Mv6tV6.js} +32 -32
  84. package/client/dist/assets/{jira-api-DrGxiD9p.js → jira-api-BYbEPlkr.js} +1 -1
  85. package/client/dist/assets/{jobs-DSp9DoD_.js → jobs-6_-r75yC.js} +1 -1
  86. package/client/dist/assets/{jobs-C6qmvUAi.js → jobs-B1yqyId5.js} +1 -1
  87. package/client/dist/assets/{jobs-DoFaEl9g.js → jobs-BFuV7ttH.js} +1 -1
  88. package/client/dist/assets/{jobs-DTQO08nJ.js → jobs-BKa8LuwA.js} +1 -1
  89. package/client/dist/assets/{jobs-DrF8Do8s.js → jobs-BKiK-ZWh.js} +1 -1
  90. package/client/dist/assets/{jobs-DLHdDkHc.js → jobs-DmKV7b7d.js} +1 -1
  91. package/client/dist/assets/{jobs-C9j2PuwW.js → jobs-KG4Sn12X.js} +1 -1
  92. package/client/dist/assets/{jobs-Dpw6AEOP.js → jobs-pPv4KWjb.js} +1 -1
  93. package/client/dist/assets/loop-layout-BF8xMiNv.js +7 -0
  94. package/client/dist/assets/loops-B4_D-nbg.js +1 -0
  95. package/client/dist/assets/loops-BJDY9FTh.js +1 -0
  96. package/client/dist/assets/loops-BO3V8244.js +1 -0
  97. package/client/dist/assets/loops-C-hZK8pf.js +1 -0
  98. package/client/dist/assets/loops-CDOWZ0ci.js +1 -0
  99. package/client/dist/assets/loops-Dv849ckF.js +1 -0
  100. package/client/dist/assets/loops-Q9LIgGkq.js +1 -0
  101. package/client/dist/assets/loops-eUnCfLjC.js +1 -0
  102. package/client/dist/assets/{project-repositories-9Wzs0coQ.js → project-repositories-CSnfzUpg.js} +1 -1
  103. package/client/dist/assets/settings-3o4Ntzi5.js +1 -0
  104. package/client/dist/assets/settings-B97jlkwD.js +1 -0
  105. package/client/dist/assets/settings-BTaT_bsS.js +1 -0
  106. package/client/dist/assets/settings-CT8w7WiC.js +1 -0
  107. package/client/dist/assets/settings-Cvr8_tvh.js +1 -0
  108. package/client/dist/assets/settings-Dn1qgAC8.js +1 -0
  109. package/client/dist/assets/settings-EShDdg4J.js +1 -0
  110. package/client/dist/assets/settings-tfLhQZRN.js +1 -0
  111. package/client/dist/assets/{setup-Dwzt5nO1.js → setup-CBMu3tqH.js} +1 -1
  112. package/client/dist/assets/{setup-B5FHuxvB.js → setup-CPh-e6J2.js} +1 -1
  113. package/client/dist/assets/{setup-DpqzaEEA.js → setup-CRKLp_ke.js} +1 -1
  114. package/client/dist/assets/{setup-CROyqD5N.js → setup-Cy302v4J.js} +1 -1
  115. package/client/dist/assets/{setup-C9Fy9PKQ.js → setup-D681vTPf.js} +1 -1
  116. package/client/dist/assets/{setup-BihzXadx.js → setup-DYK0VBkE.js} +1 -1
  117. package/client/dist/assets/{setup-BtC6Hg4K.js → setup-KAuiIiVs.js} +1 -1
  118. package/client/dist/assets/{setup-zLEDnG7N.js → setup-OGX-oCfI.js} +1 -1
  119. package/client/dist/assets/{spending-T5GM7wpn.js → spending-HBSk-6jv.js} +1 -1
  120. package/client/dist/assets/{useDesktop-QogiN0zR.js → useDesktop-0unHDBJJ.js} +1 -1
  121. package/client/dist/assets/useRuntimeRuns-BN1rhyEm.js +1 -0
  122. package/client/dist/assets/{useSharedWebSocket-Dz-HI6De.js → useSharedWebSocket-BZMrX4jr.js} +2 -2
  123. package/client/dist/index.html +25 -25
  124. package/docs/agent-live-steering.md +16 -0
  125. package/docs/cli.md +7 -7
  126. package/docs/codex.md +2 -2
  127. package/docs/customizing.md +1 -1
  128. package/docs/gemini.md +1 -1
  129. package/docs/getting-started.md +1 -1
  130. package/docs/guide/de/integrations/7-local-engines.md +1 -1
  131. package/docs/guide/de/pipeline/1-rails-and-jobs.md +8 -6
  132. package/docs/guide/de/pipeline/2-the-job-detail-view.md +11 -2
  133. package/docs/guide/de/pipeline/4-picking-an-engine-per-rail.md +2 -2
  134. package/docs/guide/de/pipeline/5-the-loop-builder.md +24 -5
  135. package/docs/guide/en/integrations/7-local-engines.md +1 -1
  136. package/docs/guide/en/pipeline/1-rails-and-jobs.md +8 -6
  137. package/docs/guide/en/pipeline/2-the-job-detail-view.md +11 -2
  138. package/docs/guide/en/pipeline/4-picking-an-engine-per-rail.md +2 -2
  139. package/docs/guide/en/pipeline/5-the-loop-builder.md +34 -5
  140. package/docs/guide/en/settings/3-pipeline-telemetry-and-diagnostics.md +1 -1
  141. package/docs/guide/es/integrations/7-local-engines.md +1 -1
  142. package/docs/guide/es/pipeline/1-rails-and-jobs.md +8 -6
  143. package/docs/guide/es/pipeline/2-the-job-detail-view.md +11 -2
  144. package/docs/guide/es/pipeline/4-picking-an-engine-per-rail.md +2 -2
  145. package/docs/guide/es/pipeline/5-the-loop-builder.md +30 -5
  146. package/docs/guide/es/settings/3-pipeline-telemetry-and-diagnostics.md +1 -2
  147. package/docs/guide/fr/integrations/7-local-engines.md +1 -1
  148. package/docs/guide/fr/pipeline/1-rails-and-jobs.md +8 -6
  149. package/docs/guide/fr/pipeline/2-the-job-detail-view.md +11 -2
  150. package/docs/guide/fr/pipeline/4-picking-an-engine-per-rail.md +2 -2
  151. package/docs/guide/fr/pipeline/5-the-loop-builder.md +24 -5
  152. package/docs/guide/it/integrations/7-local-engines.md +1 -1
  153. package/docs/guide/it/pipeline/1-rails-and-jobs.md +8 -6
  154. package/docs/guide/it/pipeline/2-the-job-detail-view.md +11 -2
  155. package/docs/guide/it/pipeline/4-picking-an-engine-per-rail.md +2 -2
  156. package/docs/guide/it/pipeline/5-the-loop-builder.md +24 -5
  157. package/docs/guide/ja/integrations/7-local-engines.md +1 -1
  158. package/docs/guide/ja/pipeline/1-rails-and-jobs.md +8 -6
  159. package/docs/guide/ja/pipeline/2-the-job-detail-view.md +11 -2
  160. package/docs/guide/ja/pipeline/4-picking-an-engine-per-rail.md +2 -2
  161. package/docs/guide/ja/pipeline/5-the-loop-builder.md +24 -5
  162. package/docs/guide/pt/integrations/7-local-engines.md +1 -1
  163. package/docs/guide/pt/pipeline/1-rails-and-jobs.md +8 -6
  164. package/docs/guide/pt/pipeline/2-the-job-detail-view.md +11 -2
  165. package/docs/guide/pt/pipeline/4-picking-an-engine-per-rail.md +2 -2
  166. package/docs/guide/pt/pipeline/5-the-loop-builder.md +24 -5
  167. package/docs/guide/zh/integrations/7-local-engines.md +1 -1
  168. package/docs/guide/zh/pipeline/1-rails-and-jobs.md +8 -6
  169. package/docs/guide/zh/pipeline/2-the-job-detail-view.md +11 -2
  170. package/docs/guide/zh/pipeline/4-picking-an-engine-per-rail.md +2 -2
  171. package/docs/guide/zh/pipeline/5-the-loop-builder.md +24 -5
  172. package/docs/internals/api-reference.md +2 -2
  173. package/docs/internals/ci-performance.md +71 -0
  174. package/docs/internals/companion-rails-as-loops-contract.md +4 -3
  175. package/docs/internals/configuration.md +3 -3
  176. package/docs/internals/core-runtime-updates.md +3 -2
  177. package/docs/internals/interactive-jobs.md +2 -2
  178. package/docs/internals/loop-step-log-explorer.md +42 -0
  179. package/docs/internals/mission-rail-cards.md +1 -1
  180. package/docs/internals/operations-runbook.md +22 -0
  181. package/docs/internals/programmatic-agent-runtime.md +130 -7
  182. package/docs/internals/project-builder.md +35 -16
  183. package/docs/internals/source-map.md +48 -2
  184. package/docs/kimi.md +2 -2
  185. package/docs/local-providers.md +1 -1
  186. package/docs/running-pipelines.md +26 -18
  187. package/docs/tracking-cost.md +10 -1
  188. package/package.json +2 -1
  189. package/server/dist/core-compat.js +8 -3
  190. package/server/dist/core-execution.js +49 -3
  191. package/server/dist/db/migrations.js +101 -0
  192. package/server/dist/desktop-db.js +28 -0
  193. package/server/dist/desktop-router.js +2 -0
  194. package/server/dist/mcp/guide.js +6 -3
  195. package/server/dist/mcp/tools/jobs.js +14 -1
  196. package/server/dist/mcp/tools/loops.js +17 -8
  197. package/server/dist/mcp/tools/rails.js +3 -3
  198. package/server/dist/modules/agent-runtime/runtime/agent-runtime-bridge.js +313 -9
  199. package/server/dist/modules/agent-runtime/runtime/agent-runtime-controls-router.js +34 -1
  200. package/server/dist/modules/agent-runtime/runtime/agent-runtime-controls.js +203 -21
  201. package/server/dist/modules/agent-runtime/runtime/agent-runtime-effective-config.js +46 -1
  202. package/server/dist/modules/agent-runtime/runtime/agent-runtime-engines.js +10 -0
  203. package/server/dist/modules/agent-runtime/runtime/agent-runtime-loader.js +68 -3
  204. package/server/dist/modules/agent-runtime/runtime/agent-runtime-metrics.js +16 -8
  205. package/server/dist/modules/agent-runtime/runtime/agent-runtime-package-gc.js +81 -0
  206. package/server/dist/modules/agent-runtime/runtime/agent-runtime-package-lock.js +37 -0
  207. package/server/dist/modules/agent-runtime/runtime/agent-runtime-package.js +30 -24
  208. package/server/dist/modules/agent-runtime/runtime/agent-runtime-retention-host.js +87 -0
  209. package/server/dist/modules/agent-runtime/runtime/agent-runtime-retention-quarantine.js +231 -0
  210. package/server/dist/modules/agent-runtime/runtime/agent-runtime-retention-records.js +32 -0
  211. package/server/dist/modules/agent-runtime/runtime/agent-runtime-retention.js +102 -0
  212. package/server/dist/modules/agent-runtime/runtime/agent-runtime-settings-router.js +12 -7
  213. package/server/dist/modules/agent-runtime/runtime/agent-runtime-settings.js +57 -13
  214. package/server/dist/modules/agents/runtime/agent-catalog.js +32 -0
  215. package/server/dist/modules/agents/runtime/agent-refine-manager.js +12 -0
  216. package/server/dist/modules/agents/runtime/agent-role-descriptor.js +64 -0
  217. package/server/dist/modules/agents/runtime/profiles-router.js +26 -34
  218. package/server/dist/modules/builder/runtime/milestone-chain.js +121 -73
  219. package/server/dist/modules/delivery/runtime/definition-fork.js +158 -0
  220. package/server/dist/modules/delivery/runtime/delivery-evidence.js +56 -10
  221. package/server/dist/modules/delivery/runtime/isolated-settlement-reconstruction.js +99 -0
  222. package/server/dist/modules/delivery/runtime/isolated-settlement-store.js +53 -0
  223. package/server/dist/modules/delivery/runtime/multi-repo-execution-store.js +3 -1
  224. package/server/dist/modules/delivery/runtime/rail-isolated-launch.js +388 -203
  225. package/server/dist/modules/delivery/runtime/rail-launch-parser.js +3 -2
  226. package/server/dist/modules/delivery/runtime/rail-pr-store.js +6 -1
  227. package/server/dist/modules/delivery/runtime/rails-router.js +66 -10
  228. package/server/dist/modules/execution/runtime/queue-manager.js +11 -2
  229. package/server/dist/modules/loops/runtime/builtin-loops.js +70 -0
  230. package/server/dist/modules/loops/runtime/definition-cancellation.js +31 -0
  231. package/server/dist/modules/loops/runtime/legacy-launch-telemetry.js +78 -0
  232. package/server/dist/modules/loops/runtime/loop-command-catalog.js +13 -12
  233. package/server/dist/modules/loops/runtime/loop-compat.js +219 -0
  234. package/server/dist/modules/loops/runtime/loop-core-factory.js +42 -0
  235. package/server/dist/modules/loops/runtime/loop-definition-controls.js +48 -0
  236. package/server/dist/modules/loops/runtime/loop-definition-events.js +145 -0
  237. package/server/dist/modules/loops/runtime/loop-definition-recovery.js +106 -0
  238. package/server/dist/modules/loops/runtime/loop-definition-run.js +36 -0
  239. package/server/dist/modules/loops/runtime/loop-definition.js +246 -0
  240. package/server/dist/modules/loops/runtime/loop-effect.js +10 -1
  241. package/server/dist/modules/loops/runtime/loop-executors.js +63 -3
  242. package/server/dist/modules/loops/runtime/loop-factory.js +35 -15
  243. package/server/dist/modules/loops/runtime/loop-graph.js +84 -8
  244. package/server/dist/modules/loops/runtime/loop-migration.js +36 -0
  245. package/server/dist/modules/loops/runtime/loop-preview.js +10 -0
  246. package/server/dist/modules/loops/runtime/loop-run-manager.js +206 -13
  247. package/server/dist/modules/loops/runtime/loop-runs-store.js +271 -7
  248. package/server/dist/modules/loops/runtime/loop-templates.js +205 -45
  249. package/server/dist/modules/loops/runtime/loops-router.js +246 -29
  250. package/server/dist/modules/loops/runtime/loops-store.js +140 -20
  251. package/server/dist/modules/missions/runtime/agent-operator-prompt.js +14 -11
  252. package/server/dist/modules/specs/runtime/spec-addenda.js +28 -0
  253. package/server/dist/project-registry.js +87 -51
  254. package/server/dist/project-router-jobs.js +17 -6
  255. package/server/dist/project-router-loop-runs.js +200 -0
  256. package/server/dist/project-router-spending.js +17 -0
  257. package/server/dist/project-router.js +8 -6
  258. package/server/dist/schemas/agent-runtime.schema.json +93 -1
  259. package/server/dist/schemas/workflow-definition.schema.json +312 -0
  260. package/server/dist/vitest-setup.js +22 -0
  261. package/server/dist/worktree-overlay.js +1 -1
  262. package/client/dist/assets/AgentsPage-DfHWgP_x.js +0 -87
  263. package/client/dist/assets/DesktopAnalyticsPage-tc0p4jJW.js +0 -1
  264. package/client/dist/assets/InteractiveJobComposer-DFPpdg2D.js +0 -19
  265. package/client/dist/assets/JobDetailModal-BdOv-l-M.js +0 -1
  266. package/client/dist/assets/LoopBuilderPage-BemvUOxy.js +0 -7
  267. package/client/dist/assets/LoopPreviewModal-C6hNAeYN.js +0 -1
  268. package/client/dist/assets/LoopsPage-BZr0quvh.js +0 -1
  269. package/client/dist/assets/TemplatePreviewModal-Cejcquah.js +0 -1
  270. package/client/dist/assets/agentRuntime-BUimiX__.js +0 -1
  271. package/client/dist/assets/agentRuntime-BcN97sAB.js +0 -1
  272. package/client/dist/assets/agentRuntime-Ckyg-ahT.js +0 -1
  273. package/client/dist/assets/agentRuntime-DJCwyX4t.js +0 -1
  274. package/client/dist/assets/agentRuntime-DVzPJOl0.js +0 -1
  275. package/client/dist/assets/agentRuntime-V9AZTG3c.js +0 -1
  276. package/client/dist/assets/agentRuntime-bAAjw1vw.js +0 -1
  277. package/client/dist/assets/agentRuntime-v4qKAYH-.js +0 -1
  278. package/client/dist/assets/agentstudio-BNUth0uj.js +0 -1
  279. package/client/dist/assets/agentstudio-BNdB5hkr.js +0 -1
  280. package/client/dist/assets/agentstudio-C7-bt8FO.js +0 -1
  281. package/client/dist/assets/agentstudio-C8uNchpV.js +0 -1
  282. package/client/dist/assets/agentstudio-CKabyMlg.js +0 -1
  283. package/client/dist/assets/agentstudio-CN2pokQu.js +0 -1
  284. package/client/dist/assets/agentstudio-y2dVDXeM.js +0 -1
  285. package/client/dist/assets/analytics-BlypLLR6.js +0 -1
  286. package/client/dist/assets/builder-765NeYTp.js +0 -1
  287. package/client/dist/assets/builder-8MG3V6ea.js +0 -1
  288. package/client/dist/assets/builder-B-1UBs5K.js +0 -1
  289. package/client/dist/assets/builder-BTiGnPT0.js +0 -1
  290. package/client/dist/assets/builder-Cx9Rz-7u.js +0 -1
  291. package/client/dist/assets/builder-DKFMELBl.js +0 -1
  292. package/client/dist/assets/builder-OcmKrC0h.js +0 -1
  293. package/client/dist/assets/builder-P9qVBXFZ.js +0 -1
  294. package/client/dist/assets/common-B5AZNYMH.js +0 -1
  295. package/client/dist/assets/common-BFZ0c_vN.js +0 -1
  296. package/client/dist/assets/common-BttQx3z4.js +0 -1
  297. package/client/dist/assets/common-CM65k_-e.js +0 -1
  298. package/client/dist/assets/common-D4mvFFlu.js +0 -1
  299. package/client/dist/assets/common-TZ9Ny96S.js +0 -1
  300. package/client/dist/assets/common-nFpSF4GC.js +0 -1
  301. package/client/dist/assets/dashboard-B9uWNGO2.js +0 -1
  302. package/client/dist/assets/dashboard-BIwmO9wc.js +0 -1
  303. package/client/dist/assets/dashboard-BV4vOZkR.js +0 -1
  304. package/client/dist/assets/dashboard-Bf6MPVsM.js +0 -1
  305. package/client/dist/assets/dashboard-C8klWVvZ.js +0 -1
  306. package/client/dist/assets/dashboard-D1ORhPF0.js +0 -1
  307. package/client/dist/assets/dashboard-DSubvs9x.js +0 -1
  308. package/client/dist/assets/dashboard-px_vlRx_.js +0 -1
  309. package/client/dist/assets/index-C51x61Bz.css +0 -2
  310. package/client/dist/assets/loops-B7YpGizO.js +0 -1
  311. package/client/dist/assets/loops-BomD2J-h.js +0 -1
  312. package/client/dist/assets/loops-BrQHSQw3.js +0 -1
  313. package/client/dist/assets/loops-BvBwvTPA.js +0 -1
  314. package/client/dist/assets/loops-CODk6Slz.js +0 -1
  315. package/client/dist/assets/loops-DC6k-Ym-.js +0 -1
  316. package/client/dist/assets/loops-DSEg8-uY.js +0 -1
  317. package/client/dist/assets/loops-DhCoXD_v.js +0 -1
  318. package/client/dist/assets/settings-BsehKpty.js +0 -1
  319. package/client/dist/assets/settings-CQWob3SB.js +0 -1
  320. package/client/dist/assets/settings-CgCl0hzy.js +0 -1
  321. package/client/dist/assets/settings-DLRLd22L.js +0 -1
  322. package/client/dist/assets/settings-Dn5prAFl.js +0 -1
  323. package/client/dist/assets/settings-HZSu-K4l.js +0 -1
  324. package/client/dist/assets/settings-p4OVIyRh.js +0 -1
  325. package/client/dist/assets/settings-rddaldUp.js +0 -1
  326. package/client/dist/assets/useRuntimeRuns-Dqmz9fS9.js +0 -1
  327. package/docs/guide/de/pipeline/3-batch-implement-and-multi-feature.md +0 -84
  328. package/docs/guide/en/pipeline/3-batch-implement-and-multi-feature.md +0 -126
  329. package/docs/guide/es/pipeline/3-batch-implement-and-multi-feature.md +0 -114
  330. package/docs/guide/fr/pipeline/3-batch-implement-and-multi-feature.md +0 -84
  331. package/docs/guide/it/pipeline/3-batch-implement-and-multi-feature.md +0 -84
  332. package/docs/guide/ja/pipeline/3-batch-implement-and-multi-feature.md +0 -84
  333. package/docs/guide/pt/pipeline/3-batch-implement-and-multi-feature.md +0 -84
  334. package/docs/guide/zh/pipeline/3-batch-implement-and-multi-feature.md +0 -84
  335. package/server/dist/modules/loops/runtime/loop-templates-ported.js +0 -675
  336. /package/client/dist/assets/{LoopBuilderPage-DtxX27Jz.css → loop-layout-DtxX27Jz.css} +0 -0
@@ -9,6 +9,7 @@ const workspace_resolution_1 = require("./workspace-resolution");
9
9
  const ai_invocations_1 = require("./modules/accounting/runtime/ai-invocations");
10
10
  const spending_1 = require("./modules/accounting/runtime/spending");
11
11
  const ticket_store_1 = require("./modules/specs/runtime/ticket-store");
12
+ const legacy_launch_telemetry_1 = require("./modules/loops/runtime/legacy-launch-telemetry");
12
13
  /**
13
14
  * Parse + clamp a `tzOffsetMinutes` query param (minutes east of UTC, the value
14
15
  * `Date.prototype.getTimezoneOffset()` negates). Non-numeric / out-of-range
@@ -39,6 +40,22 @@ function localDayBoundsUtc(tzOffsetMinutes, now = Date.now()) {
39
40
  }
40
41
  function registerSpendingRoutes(deps) {
41
42
  const { router, registry, ctx, ticketPath } = deps;
43
+ router.get('/:projectId/analytics/legacy-launches', (req, res) => {
44
+ if (req.query.since !== undefined && typeof req.query.since !== 'string') {
45
+ res.status(400).json({ error: 'invalid_since' });
46
+ return;
47
+ }
48
+ try {
49
+ res.json({ ...(0, legacy_launch_telemetry_1.readLegacyLaunchSummary)(ctx(req).db, req.query.since), retirementEvidence: 'not-evaluated' });
50
+ }
51
+ catch (error) {
52
+ if (error instanceof RangeError) {
53
+ res.status(400).json({ error: 'invalid_since' });
54
+ return;
55
+ }
56
+ res.status(503).json({ error: 'legacy_telemetry_unavailable' });
57
+ }
58
+ });
42
59
  // Build a YAML-store-backed title resolver for getSpending's 4th arg
43
60
  // (BUG-ANALYTICS-18/36). Without it, topTickets keeps ticketTitle:null and the
44
61
  // client mislabels every live ticket "Deleted ticket #N". Returns undefined
@@ -262,9 +262,11 @@ function createProjectRouter(registry) {
262
262
  res.json({ blueprint: snapshot.blueprint, progress: snapshot.progress });
263
263
  });
264
264
  // Milestone launch chain (premium-milestone-progress D3): "Launch Milestone
265
- // N" is server-owned — chunked into ≤3-spec rails, launched through the
266
- // ordinary rails launch route, and (sequential) chained on each chunk's
267
- // delivered branch. The client keeps NO plan in browser storage.
265
+ // N" is server-owned — one spec per rail in dependency order, launched
266
+ // through the ordinary rails launch route and chained on each spec's
267
+ // delivered branch. Always sequential: the retired `mode: 'parallel'` is
268
+ // accepted for old clients and runs sequentially (the response echoes
269
+ // `mode: 'sequential'`). `autoAdvance` defaults to true.
268
270
  router.post('/:projectId/blueprint/milestones/:n/launch', async (req, res) => {
269
271
  const projectCtx = ctx(req);
270
272
  const n = Number.parseInt(String(req.params.n), 10);
@@ -274,7 +276,7 @@ function createProjectRouter(registry) {
274
276
  }
275
277
  const rawMode = (req.body ?? {}).mode;
276
278
  if (rawMode !== undefined && rawMode !== 'sequential' && rawMode !== 'parallel') {
277
- res.status(400).json({ error: "mode must be 'sequential' or 'parallel'" });
279
+ res.status(400).json({ error: "mode must be 'sequential'" });
278
280
  return;
279
281
  }
280
282
  const rawAuto = (req.body ?? {}).autoAdvance;
@@ -288,9 +290,9 @@ function createProjectRouter(registry) {
288
290
  return;
289
291
  }
290
292
  try {
291
- const result = await chains.start(n, rawMode ?? 'sequential', { autoAdvance: rawAuto });
293
+ const result = await chains.start(n, { autoAdvance: rawAuto });
292
294
  if (result.ok) {
293
- res.status(202).json({ chainId: result.chainId, launched: result.launched, pending: result.pending });
295
+ res.status(202).json({ chainId: result.chainId, mode: 'sequential', launched: result.launched, pending: result.pending });
294
296
  }
295
297
  else {
296
298
  res.status(result.status).json({ error: result.error, ...(result.detail ? { detail: result.detail } : {}), ...(result.chainId ? { chainId: result.chainId } : {}) });
@@ -13,7 +13,7 @@
13
13
  "verification": { "type": "object", "additionalProperties": false, "properties": { "maxConcurrency": { "type": "integer", "minimum": 1, "maximum": 4 } } }
14
14
  } },
15
15
  "guardrails": { "type": "object", "additionalProperties": false, "properties": { "plan-validation": { "type": "boolean" }, "genuine-blocking-question": { "type": "boolean" }, "plan-language-hint": { "type": "boolean" }, "frozen-plan-writes": { "type": "boolean" }, "primary-language": { "type": "boolean" }, "duplicate-sibling": { "type": "boolean" }, "one-test-per-module": { "type": "boolean" }, "empty-write": { "type": "boolean" }, "evidence-gated-ticking": { "type": "boolean" }, "inventory-retry": { "type": "boolean" }, "synthetic-corrections": { "type": "boolean" }, "silent-group-closure": { "type": "boolean" }, "verify-per-group": { "type": "boolean" }, "test-reachability": { "type": "boolean" }, "exit-code-honesty": { "type": "boolean" }, "environment-repair": { "type": "boolean" }, "lockfile-repair": { "type": "boolean" }, "verify-idle-timeout": { "type": "boolean" } } },
16
- "rolePrompts": { "type": "object", "additionalProperties": false, "properties": {
16
+ "rolePrompts": { "type": "object", "propertyNames": { "pattern": "^[a-z][a-z0-9-]{0,63}$" }, "additionalProperties": { "type": "string", "minLength": 1, "maxLength": 20000, "pattern": "\\S" }, "properties": {
17
17
  "architect": { "type": "string", "minLength": 1, "maxLength": 20000, "pattern": "\\S" },
18
18
  "developer": { "type": "string", "minLength": 1, "maxLength": 20000, "pattern": "\\S" },
19
19
  "reviewer": { "type": "string", "minLength": 1, "maxLength": 20000, "pattern": "\\S" },
@@ -35,6 +35,98 @@
35
35
  } }
36
36
  ] } },
37
37
  "fixer": { "$ref": "#/definitions/agent" },
38
+ "roles": {
39
+ "type": "object",
40
+ "propertyNames": {
41
+ "pattern": "^[a-z][a-z0-9-]{0,63}$",
42
+ "not": {
43
+ "const": "fixer"
44
+ }
45
+ },
46
+ "additionalProperties": {
47
+ "type": "object",
48
+ "additionalProperties": false,
49
+ "required": [
50
+ "provider",
51
+ "access",
52
+ "artifacts"
53
+ ],
54
+ "dependencies": {
55
+ "escalation": [
56
+ "model"
57
+ ]
58
+ },
59
+ "properties": {
60
+ "effort": {
61
+ "$ref": "#/definitions/effort"
62
+ },
63
+ "thinking": {
64
+ "type": "string",
65
+ "enum": [
66
+ "on",
67
+ "off"
68
+ ],
69
+ "description": "OpenAI-compatible engines only: private thinking (chat_template_kwargs.enable_thinking). Default off."
70
+ },
71
+ "escalation": {
72
+ "type": "object",
73
+ "additionalProperties": false,
74
+ "required": [
75
+ "model"
76
+ ],
77
+ "properties": {
78
+ "model": {
79
+ "type": "string",
80
+ "minLength": 1,
81
+ "maxLength": 256,
82
+ "pattern": "^[^-\\r\\n\\u0000][^\\r\\n\\u0000]*$"
83
+ },
84
+ "effort": {
85
+ "$ref": "#/definitions/effort"
86
+ }
87
+ }
88
+ },
89
+ "provider": {
90
+ "$ref": "#/definitions/id"
91
+ },
92
+ "model": {
93
+ "type": "string",
94
+ "minLength": 1,
95
+ "maxLength": 256,
96
+ "pattern": "^[^-\\r\\n\\u0000][^\\r\\n\\u0000]*$"
97
+ },
98
+ "maxTurns": {
99
+ "$ref": "#/definitions/positiveInteger"
100
+ },
101
+ "access": {
102
+ "enum": [
103
+ "read",
104
+ "write"
105
+ ]
106
+ },
107
+ "artifacts": {
108
+ "enum": [
109
+ "none",
110
+ "tasks-checkboxes",
111
+ "all"
112
+ ]
113
+ },
114
+ "prompt": {
115
+ "type": "string",
116
+ "minLength": 1,
117
+ "maxLength": 20000,
118
+ "pattern": "\\S"
119
+ },
120
+ "openspecSkill": {
121
+ "enum": [
122
+ "openspec-ff-change",
123
+ "openspec-apply-change",
124
+ "openspec-verify-change"
125
+ ]
126
+ }
127
+ }
128
+ }
129
+ },
38
130
  "agents": { "type": "object", "additionalProperties": false, "required": ["architect", "developer", "reviewer"], "properties": {
39
131
  "architect": { "$ref": "#/definitions/agent" }, "developer": { "$ref": "#/definitions/agent" }, "reviewer": { "$ref": "#/definitions/agent" }
40
132
  } },
@@ -0,0 +1,312 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://specrails.dev/schemas/workflow-definition/1",
4
+ "type": "object",
5
+ "additionalProperties": false,
6
+ "required": [
7
+ "schemaVersion",
8
+ "id",
9
+ "version",
10
+ "title",
11
+ "journal",
12
+ "change",
13
+ "entry",
14
+ "maxTransitions",
15
+ "roles",
16
+ "nodes"
17
+ ],
18
+ "properties": {
19
+ "schemaVersion": {
20
+ "const": 1
21
+ },
22
+ "id": {
23
+ "type": "string",
24
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$"
25
+ },
26
+ "version": {
27
+ "type": "string",
28
+ "pattern": "^[0-9a-f]{64}$"
29
+ },
30
+ "title": {
31
+ "type": "string",
32
+ "minLength": 1,
33
+ "maxLength": 120
34
+ },
35
+ "journal": {
36
+ "enum": [
37
+ "ledger-only",
38
+ "implementation"
39
+ ]
40
+ },
41
+ "change": {
42
+ "enum": [
43
+ "new",
44
+ "existing",
45
+ "none"
46
+ ]
47
+ },
48
+ "entry": {
49
+ "$ref": "#/$defs/nodeId"
50
+ },
51
+ "maxTransitions": {
52
+ "type": "integer",
53
+ "minimum": 1,
54
+ "maximum": 10000
55
+ },
56
+ "budget": {
57
+ "type": "object",
58
+ "additionalProperties": false,
59
+ "properties": {
60
+ "maxCostUsd": {
61
+ "type": "number",
62
+ "exclusiveMinimum": 0
63
+ },
64
+ "maxTokens": {
65
+ "type": "integer",
66
+ "minimum": 1
67
+ },
68
+ "maxDurationMs": {
69
+ "type": "integer",
70
+ "minimum": 1000
71
+ }
72
+ }
73
+ },
74
+ "policies": {
75
+ "type": "object",
76
+ "additionalProperties": false,
77
+ "properties": {
78
+ "failFast": {
79
+ "type": "integer",
80
+ "minimum": 1,
81
+ "maximum": 10,
82
+ "default": 2
83
+ },
84
+ "noProgress": {
85
+ "type": "integer",
86
+ "minimum": 1,
87
+ "maximum": 10,
88
+ "default": 2
89
+ },
90
+ "historyMaxChars": {
91
+ "type": "integer",
92
+ "minimum": 200,
93
+ "maximum": 20000,
94
+ "default": 1500
95
+ },
96
+ "concurrency": {
97
+ "type": "integer",
98
+ "minimum": 1,
99
+ "maximum": 8,
100
+ "default": 1
101
+ }
102
+ }
103
+ },
104
+ "roles": {
105
+ "type": "array",
106
+ "items": {
107
+ "$ref": "#/$defs/roleId"
108
+ },
109
+ "uniqueItems": true
110
+ },
111
+ "nodes": {
112
+ "type": "object",
113
+ "minProperties": 1,
114
+ "propertyNames": {
115
+ "$ref": "#/$defs/nodeId"
116
+ },
117
+ "additionalProperties": {
118
+ "$ref": "#/$defs/node"
119
+ }
120
+ },
121
+ "components": {
122
+ "type": "object",
123
+ "propertyNames": {
124
+ "pattern": "^[a-z0-9][a-z0-9-]{0,63}$"
125
+ },
126
+ "additionalProperties": {
127
+ "$ref": "#/$defs/componentBody"
128
+ }
129
+ },
130
+ "delivery": {
131
+ "type": "object",
132
+ "additionalProperties": false,
133
+ "properties": {
134
+ "requiresVerified": {
135
+ "type": "boolean"
136
+ }
137
+ }
138
+ }
139
+ },
140
+ "$defs": {
141
+ "nodeId": {
142
+ "type": "string",
143
+ "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,119}$",
144
+ "not": {
145
+ "enum": [
146
+ "START",
147
+ "END",
148
+ "__start__",
149
+ "__end__",
150
+ "next"
151
+ ]
152
+ }
153
+ },
154
+ "roleId": {
155
+ "type": "string",
156
+ "pattern": "^[a-z][a-z0-9-]{0,63}$"
157
+ },
158
+ "engine": {
159
+ "type": "object",
160
+ "additionalProperties": false,
161
+ "required": [
162
+ "provider"
163
+ ],
164
+ "properties": {
165
+ "provider": {
166
+ "type": "string"
167
+ },
168
+ "model": {
169
+ "type": "string"
170
+ },
171
+ "effort": {
172
+ "type": "string"
173
+ },
174
+ "thinking": {
175
+ "enum": [
176
+ "on",
177
+ "off"
178
+ ]
179
+ }
180
+ }
181
+ },
182
+ "retry": {
183
+ "type": "object",
184
+ "additionalProperties": false,
185
+ "properties": {
186
+ "maxAttempts": {
187
+ "type": "integer",
188
+ "minimum": 1,
189
+ "maximum": 10
190
+ },
191
+ "backoffMs": {
192
+ "type": "integer",
193
+ "minimum": 0,
194
+ "maximum": 600000
195
+ },
196
+ "retryOn": {
197
+ "type": "array",
198
+ "items": {
199
+ "enum": [
200
+ "idle_timeout",
201
+ "timeout",
202
+ "provider_request_error",
203
+ "session_not_found",
204
+ "invalid_structured_output"
205
+ ]
206
+ }
207
+ }
208
+ }
209
+ },
210
+ "ends": {
211
+ "type": "object",
212
+ "propertyNames": {
213
+ "pattern": "^[a-z][a-z0-9-]{0,31}$"
214
+ },
215
+ "additionalProperties": {
216
+ "oneOf": [
217
+ {
218
+ "$ref": "#/$defs/nodeId"
219
+ },
220
+ {
221
+ "type": "null"
222
+ }
223
+ ]
224
+ }
225
+ },
226
+ "node": {
227
+ "type": "object",
228
+ "additionalProperties": false,
229
+ "required": [
230
+ "kind",
231
+ "params",
232
+ "ends"
233
+ ],
234
+ "properties": {
235
+ "kind": {
236
+ "enum": [
237
+ "prompt",
238
+ "role-turn",
239
+ "decider",
240
+ "condition",
241
+ "assign",
242
+ "verify",
243
+ "shell",
244
+ "openspec-validate",
245
+ "openspec-archive",
246
+ "approval",
247
+ "question",
248
+ "gate",
249
+ "map",
250
+ "join",
251
+ "component",
252
+ "implementation",
253
+ "end"
254
+ ]
255
+ },
256
+ "params": {
257
+ "type": "object"
258
+ },
259
+ "ends": {
260
+ "$ref": "#/$defs/ends"
261
+ },
262
+ "retry": {
263
+ "$ref": "#/$defs/retry"
264
+ },
265
+ "label": {
266
+ "type": "string",
267
+ "maxLength": 80
268
+ }
269
+ }
270
+ },
271
+ "componentBody": {
272
+ "type": "object",
273
+ "additionalProperties": false,
274
+ "required": [
275
+ "entry",
276
+ "nodes"
277
+ ],
278
+ "properties": {
279
+ "entry": {
280
+ "$ref": "#/$defs/nodeId"
281
+ },
282
+ "maxTransitions": {
283
+ "type": "integer",
284
+ "minimum": 1,
285
+ "maximum": 10000
286
+ },
287
+ "inputs": {
288
+ "type": "array",
289
+ "items": {
290
+ "type": "string"
291
+ }
292
+ },
293
+ "outputs": {
294
+ "type": "array",
295
+ "items": {
296
+ "type": "string"
297
+ }
298
+ },
299
+ "nodes": {
300
+ "type": "object",
301
+ "minProperties": 1,
302
+ "propertyNames": {
303
+ "$ref": "#/$defs/nodeId"
304
+ },
305
+ "additionalProperties": {
306
+ "$ref": "#/$defs/node"
307
+ }
308
+ }
309
+ }
310
+ }
311
+ }
312
+ }
@@ -6,6 +6,28 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const fs_1 = require("fs");
7
7
  const os_1 = __importDefault(require("os"));
8
8
  const path_1 = __importDefault(require("path"));
9
+ const supertest_1 = __importDefault(require("supertest"));
10
+ // Supertest starts fixtures on the default (usually IPv6) wildcard socket but
11
+ // builds an IPv4 URL. On hosts with separate port namespaces that URL can reach
12
+ // an unrelated local service. Connect to the family actually owned by the fixture.
13
+ // Keep Supertest responsible for starting and closing its ephemeral servers.
14
+ const transportMarker = Symbol.for('specrails.supertest.address-family');
15
+ const testPrototype = supertest_1.default.Test.prototype;
16
+ if (!testPrototype[transportMarker]) {
17
+ const serverAddress = testPrototype.serverAddress;
18
+ testPrototype.serverAddress = function (server, requestPath) {
19
+ const original = serverAddress.call(this, server, requestPath);
20
+ const address = server.address();
21
+ if (address && typeof address !== 'string' && address.family === 'IPv6'
22
+ && (address.address === '::' || address.address === '::1')) {
23
+ const url = new URL(original);
24
+ url.hostname = '[::1]';
25
+ return url.toString();
26
+ }
27
+ return original;
28
+ };
29
+ testPrototype[transportMarker] = true;
30
+ }
9
31
  /**
10
32
  * Test safety net: NEVER let a test write the relocation registry into the
11
33
  * developer's real `$HOME/.specrails/registry.json`.
@@ -511,7 +511,7 @@ function refreshLegacyInstructions(text) {
511
511
  return text.replace(/<!-- specrails-managed:start -->[\s\S]*?<!-- specrails-managed:end -->/g, block => {
512
512
  if (!block.includes('skills/sr-*'))
513
513
  return block;
514
- return '<!-- specrails-managed:start -->\n\n# Specrails agent runtime\n\nFollow the frozen repository scope and official OpenSpec workflow supplied for your role. The host coordinates architect, developer, verification and reviewer; do not launch nested implement or batch-implement orchestration. Read project README, manifests, contracts and relevant nested instructions. Report incomplete tasks and permission blockers with their repository and path.\n\n<!-- specrails-managed:end -->';
514
+ return '<!-- specrails-managed:start -->\n\n# Specrails agent runtime\n\nFollow the frozen repository scope and official OpenSpec workflow supplied for your role. The host coordinates architect, developer, verification and reviewer; do not launch nested implement orchestration. Read project README, manifests, contracts and relevant nested instructions. Report incomplete tasks and permission blockers with their repository and path.\n\n<!-- specrails-managed:end -->';
515
515
  });
516
516
  }
517
517
  /** Copy `src` → `dest` only when `dest` does not exist. Records `rel`. */