specrails-desktop 2.55.0 → 2.56.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 (368) hide show
  1. package/cli/dist/args.js +80 -0
  2. package/cli/dist/desktop-client.js +125 -0
  3. package/cli/dist/desktop-control.js +339 -0
  4. package/cli/dist/format.js +45 -0
  5. package/cli/dist/help.js +68 -0
  6. package/cli/dist/output.js +47 -0
  7. package/cli/dist/run-command.js +340 -0
  8. package/cli/dist/specrails-desktop.js +41 -1107
  9. package/cli/dist/status.js +111 -0
  10. package/client/dist/assets/{ActivityFeedPage-ILXMZXcb.js → ActivityFeedPage-DdMNmVBk.js} +1 -1
  11. package/client/dist/assets/{AgentBrowserCapture-UcsupCy7.js → AgentBrowserCapture-CeerUf--.js} +1 -1
  12. package/client/dist/assets/{AgentModeAnalyticsPane-CQuxYh8B.js → AgentModeAnalyticsPane-BjGb-8rh.js} +2 -2
  13. package/client/dist/assets/{AgentModeCodePane-zPWbW7ei.js → AgentModeCodePane-8XRkQEo_.js} +2 -2
  14. package/client/dist/assets/{AgentModeJobsPane-CInByIdl.js → AgentModeJobsPane-BN3dgJOA.js} +1 -1
  15. package/client/dist/assets/{AgentsPage-BWvgxaBv.js → AgentsPage-DfHWgP_x.js} +1 -1
  16. package/client/dist/assets/{AnalyticsPage-DP3jakv-.js → AnalyticsPage-CyfhYiBn.js} +1 -1
  17. package/client/dist/assets/{CodePage-BKXiwE5a.js → CodePage-C2Nf-Q5W.js} +1 -1
  18. package/client/dist/assets/{DesktopAnalyticsPage-DryJOaMz.js → DesktopAnalyticsPage-tc0p4jJW.js} +1 -1
  19. package/client/dist/assets/{DocsDialog-BsCG9ksG.js → DocsDialog-Br3bczCp.js} +1 -1
  20. package/client/dist/assets/{DocsPage-Cc-GeKYl.js → DocsPage-BcDr2cBm.js} +1 -1
  21. package/client/dist/assets/{ExportDropdown-ClahJdDn.js → ExportDropdown-BVGKEgkd.js} +1 -1
  22. package/client/dist/assets/{InteractiveJobComposer-DfLF6N0f.js → InteractiveJobComposer-DFPpdg2D.js} +1 -1
  23. package/client/dist/assets/{JobDetailModal-DHeur9YK.js → JobDetailModal-BdOv-l-M.js} +1 -1
  24. package/client/dist/assets/{JobDetailPage-CraDKzeG.js → JobDetailPage-vBbNeRuz.js} +1 -1
  25. package/client/dist/assets/{JobsPage-CcbuSwj7.js → JobsPage-CJCtPhIz.js} +1 -1
  26. package/client/dist/assets/{LoopBuilderPage-BKtNp494.js → LoopBuilderPage-BemvUOxy.js} +1 -1
  27. package/client/dist/assets/{LoopPreviewModal-DbZd9isy.js → LoopPreviewModal-C6hNAeYN.js} +1 -1
  28. package/client/dist/assets/{LoopsPage-DEg6sIkG.js → LoopsPage-BZr0quvh.js} +1 -1
  29. package/client/dist/assets/{MinimizedChatsContext-BGtEjWsc.js → MinimizedChatsContext-D3QzgV0B.js} +1 -1
  30. package/client/dist/assets/{PluginsPage-BVqSsPzL.js → PluginsPage-DOpTV75p.js} +1 -1
  31. package/client/dist/assets/{ProjectSettingsDialog-CAjLgJAZ.js → ProjectSettingsDialog-Dkwrn0z1.js} +1 -1
  32. package/client/dist/assets/{RepositoryDeliveries-DrcrxLe0.js → RepositoryDeliveries-Du2UCf1a.js} +1 -1
  33. package/client/dist/assets/{RepositoryScopeSelector-CAGY3xW6.js → RepositoryScopeSelector-hPGZNRBm.js} +1 -1
  34. package/client/dist/assets/ReviewPacketPage-DcOq-UTA.js +4 -0
  35. package/client/dist/assets/{TemplatePreviewModal-Bqs-9fhn.js → TemplatePreviewModal-Cejcquah.js} +1 -1
  36. package/client/dist/assets/{TicketDetailModalContext-C0jQ5yOk.js → TicketDetailModalContext-DAK-NoK6.js} +1 -1
  37. package/client/dist/assets/{Trans-DtWlCJN9.js → Trans-DEbgkuAY.js} +1 -1
  38. package/client/dist/assets/{dashboard-CTfEtkqX.js → dashboard-B9uWNGO2.js} +1 -1
  39. package/client/dist/assets/{dashboard-DMklepmz.js → dashboard-BIwmO9wc.js} +1 -1
  40. package/client/dist/assets/{dashboard-DBAP2_SQ.js → dashboard-BV4vOZkR.js} +1 -1
  41. package/client/dist/assets/{dashboard-D40HP2ks.js → dashboard-Bf6MPVsM.js} +1 -1
  42. package/client/dist/assets/{dashboard-Csf1yGSN.js → dashboard-C8klWVvZ.js} +1 -1
  43. package/client/dist/assets/{dashboard-C29Qwa-L.js → dashboard-D1ORhPF0.js} +1 -1
  44. package/client/dist/assets/{dashboard-Cr4D8oMn.js → dashboard-DSubvs9x.js} +1 -1
  45. package/client/dist/assets/{dashboard-CSJzf5OT.js → dashboard-px_vlRx_.js} +1 -1
  46. package/client/dist/assets/{formatDistanceToNow-DYmvOA3R.js → formatDistanceToNow-Cc2u5FwQ.js} +1 -1
  47. package/client/dist/assets/{getTimezoneOffsetInMilliseconds-BAhW5E6V.js → getTimezoneOffsetInMilliseconds-BHm2U-w1.js} +1 -1
  48. package/client/dist/assets/index-C51x61Bz.css +2 -0
  49. package/client/dist/assets/{index-BfAZg5DG.js → index-Cxb288Rj.js} +29 -29
  50. package/client/dist/assets/{jira-api-B27Za5FP.js → jira-api-DrGxiD9p.js} +1 -1
  51. package/client/dist/assets/packet-8nn9RsU7.js +1 -0
  52. package/client/dist/assets/packet-B0H15elv.js +1 -0
  53. package/client/dist/assets/packet-BQvBgrwh.js +1 -0
  54. package/client/dist/assets/packet-BR7mO0-a.js +1 -0
  55. package/client/dist/assets/packet-BgcQ6q_K.js +1 -0
  56. package/client/dist/assets/packet-D2s92Jnn.js +1 -0
  57. package/client/dist/assets/packet-YbtcD1HS.js +1 -0
  58. package/client/dist/assets/packet-c0Qj_9eX.js +1 -0
  59. package/client/dist/assets/{project-repositories-DixIZHTA.js → project-repositories-9Wzs0coQ.js} +1 -1
  60. package/client/dist/assets/{spending-BGmZBX5B.js → spending-T5GM7wpn.js} +1 -1
  61. package/client/dist/assets/{useDesktop-CPB4cnwI.js → useDesktop-QogiN0zR.js} +1 -1
  62. package/client/dist/assets/{useRuntimeRuns-DEQ9HdAM.js → useRuntimeRuns-Dqmz9fS9.js} +1 -1
  63. package/client/dist/assets/{useSharedWebSocket-DcPRKR8R.js → useSharedWebSocket-Dz-HI6De.js} +2 -2
  64. package/client/dist/index.html +17 -17
  65. package/docs/codex.md +5 -5
  66. package/docs/customizing.md +1 -1
  67. package/docs/gemini-cli-provider-study.md +14 -14
  68. package/docs/gemini-core-support-evaluation.md +1 -1
  69. package/docs/gemini.md +5 -5
  70. package/docs/internals/README.md +6 -2
  71. package/docs/internals/adding-a-provider.md +22 -15
  72. package/docs/internals/agent-runtime-framework-evaluation.md +8 -8
  73. package/docs/internals/api-reference.md +2 -2
  74. package/docs/internals/architecture.md +9 -9
  75. package/docs/internals/browser-capture-performance.md +3 -3
  76. package/docs/internals/code-explorer-story.md +2 -2
  77. package/docs/internals/companion-rails-as-loops-contract.md +2 -2
  78. package/docs/internals/core-runtime-updates.md +5 -0
  79. package/docs/internals/embedded-browser-native-webview-evaluation.md +5 -5
  80. package/docs/internals/gemini-mcp-registration.md +2 -2
  81. package/docs/internals/global-artifacts-alignment-contract.md +1 -1
  82. package/docs/internals/global-artifacts-relocation-evaluation.md +1 -1
  83. package/docs/internals/interactive-jobs.md +8 -8
  84. package/docs/internals/legacy-implementation-notes.md +722 -0
  85. package/docs/internals/loop-step-log-explorer.md +8 -8
  86. package/docs/internals/mission-rail-cards.md +14 -14
  87. package/docs/internals/modular-architecture.md +107 -0
  88. package/docs/internals/profiles.md +1 -1
  89. package/docs/internals/programmatic-agent-runtime.md +66 -0
  90. package/docs/internals/project-builder.md +18 -18
  91. package/docs/internals/review-packet.md +8 -8
  92. package/docs/internals/safe-pr-review-flow.md +11 -11
  93. package/docs/internals/source-architecture.md +131 -0
  94. package/docs/internals/source-map.md +1356 -0
  95. package/docs/internals/spec-addenda.md +65 -9
  96. package/docs/internals/switch-to-agent-mode-design.md +11 -11
  97. package/docs/tracking-cost.md +1 -1
  98. package/package.json +5 -2
  99. package/server/dist/agent-mcp-config.js +1 -1
  100. package/server/dist/attachment-manager.js +1 -1
  101. package/server/dist/build-dirs.js +2 -2
  102. package/server/dist/config.js +0 -3
  103. package/server/dist/core-completion.js +1 -1
  104. package/server/dist/core-execution.js +1 -1
  105. package/server/dist/db/activity.js +39 -0
  106. package/server/dist/db/connection.js +41 -0
  107. package/server/dist/db/conversations.js +48 -0
  108. package/server/dist/db/jobs.js +251 -0
  109. package/server/dist/db/migrations.js +1521 -0
  110. package/server/dist/db/proposals.js +50 -0
  111. package/server/dist/db/settings.js +15 -0
  112. package/server/dist/db/stats.js +61 -0
  113. package/server/dist/db/telemetry.js +56 -0
  114. package/server/dist/db/templates.js +37 -0
  115. package/server/dist/db/types.js +2 -0
  116. package/server/dist/db.js +66 -2224
  117. package/server/dist/desktop-db.js +3 -3
  118. package/server/dist/desktop-router.js +8 -8
  119. package/server/dist/git-diagnostics.js +1 -1
  120. package/server/dist/index.js +11 -11
  121. package/server/dist/integration-branch.js +3 -14
  122. package/server/dist/jira/jira-issue-fields.js +0 -1
  123. package/server/dist/jira/jira-materializer.js +1 -1
  124. package/server/dist/jira/jira-sync-manager.js +1 -1
  125. package/server/dist/mcp/guide.js +16 -2
  126. package/server/dist/mcp/mcp-admin-router.js +1 -1
  127. package/server/dist/mcp/mcp-server.js +1 -1
  128. package/server/dist/mcp/tools/catalog.js +2 -0
  129. package/server/dist/mcp/tools/jobs.js +23 -5
  130. package/server/dist/mcp/tools/rails.js +2 -2
  131. package/server/dist/mcp/tools/recovery.js +35 -0
  132. package/server/dist/mcp/tools/specs.js +2 -2
  133. package/server/dist/mcp/tools/support.js +4 -1
  134. package/server/dist/mcp/tools/types.js +3 -3
  135. package/server/dist/mobile/mobile-gateway.js +1 -1
  136. package/server/dist/mobile/mobile-missions.js +1 -1
  137. package/server/dist/{desktop-analytics.js → modules/accounting/runtime/desktop-analytics.js} +2 -2
  138. package/server/dist/{pricing.js → modules/accounting/runtime/pricing.js} +10 -3
  139. package/server/dist/{result-event.js → modules/accounting/runtime/result-event.js} +3 -3
  140. package/server/dist/{spending.js → modules/accounting/runtime/spending.js} +0 -3
  141. package/server/dist/{telemetry-compactor.js → modules/accounting/runtime/telemetry-compactor.js} +1 -1
  142. package/server/dist/{telemetry-receiver.js → modules/accounting/runtime/telemetry-receiver.js} +2 -2
  143. package/server/dist/{agent-runtime-bridge.js → modules/agent-runtime/runtime/agent-runtime-bridge.js} +2 -2
  144. package/server/dist/{agent-runtime-controls-router.js → modules/agent-runtime/runtime/agent-runtime-controls-router.js} +16 -0
  145. package/server/dist/{agent-runtime-controls.js → modules/agent-runtime/runtime/agent-runtime-controls.js} +100 -8
  146. package/server/dist/{agent-runtime-effective-config.js → modules/agent-runtime/runtime/agent-runtime-effective-config.js} +1 -1
  147. package/server/dist/{agent-runtime-loader.js → modules/agent-runtime/runtime/agent-runtime-loader.js} +3 -3
  148. package/server/dist/{agent-runtime-paths.js → modules/agent-runtime/runtime/agent-runtime-paths.js} +1 -1
  149. package/server/dist/modules/agent-runtime/runtime/agent-runtime-recovery.js +53 -0
  150. package/server/dist/{agent-runtime-settings-router.js → modules/agent-runtime/runtime/agent-runtime-settings-router.js} +2 -2
  151. package/server/dist/{agent-runtime-settings.js → modules/agent-runtime/runtime/agent-runtime-settings.js} +3 -3
  152. package/server/dist/{agent-runtime-settlement.js → modules/agent-runtime/runtime/agent-runtime-settlement.js} +6 -6
  153. package/server/dist/{agent-defaults.js → modules/agents/runtime/agent-defaults.js} +3 -3
  154. package/server/dist/{agent-generator.js → modules/agents/runtime/agent-generator.js} +7 -7
  155. package/server/dist/{agent-refine-manager.js → modules/agents/runtime/agent-refine-manager.js} +5 -5
  156. package/server/dist/{agent-store.js → modules/agents/runtime/agent-store.js} +1 -1
  157. package/server/dist/{profile-manager.js → modules/agents/runtime/profile-manager.js} +2 -2
  158. package/server/dist/{profiles-router.js → modules/agents/runtime/profiles-router.js} +5 -5
  159. package/server/dist/{browser-capture-manager.js → modules/browser/runtime/browser-capture-manager.js} +2 -4
  160. package/server/dist/{browser-playwright.js → modules/browser/runtime/browser-playwright.js} +1 -1
  161. package/server/dist/{blueprint-chat-manager.js → modules/builder/runtime/blueprint-chat-manager.js} +7 -7
  162. package/server/dist/{blueprint-commit.js → modules/builder/runtime/blueprint-commit.js} +8 -8
  163. package/server/dist/{blueprint-draft-parser.js → modules/builder/runtime/blueprint-draft-parser.js} +1 -1
  164. package/server/dist/{blueprint-generation.js → modules/builder/runtime/blueprint-generation.js} +1 -1
  165. package/server/dist/{blueprint-operator-prompt.js → modules/builder/runtime/blueprint-operator-prompt.js} +1 -1
  166. package/server/dist/{blueprint-router.js → modules/builder/runtime/blueprint-router.js} +3 -3
  167. package/server/dist/{blueprint-spec-quality.js → modules/builder/runtime/blueprint-spec-quality.js} +1 -1
  168. package/server/dist/{milestone-chain.js → modules/builder/runtime/milestone-chain.js} +1 -1
  169. package/server/dist/{milestone-progress.js → modules/builder/runtime/milestone-progress.js} +6 -6
  170. package/server/dist/{code-activity.js → modules/code/runtime/code-activity.js} +1 -1
  171. package/server/dist/{code-explorer-router.js → modules/code/runtime/code-explorer-router.js} +5 -5
  172. package/server/dist/{file-provenance.js → modules/code/runtime/file-provenance.js} +1 -1
  173. package/server/dist/{file-story-manager.js → modules/code/runtime/file-story-manager.js} +2 -2
  174. package/server/dist/{file-story.js → modules/code/runtime/file-story.js} +2 -2
  175. package/server/dist/{file-summary-generator.js → modules/code/runtime/file-summary-generator.js} +3 -3
  176. package/server/dist/{file-summary-manager.js → modules/code/runtime/file-summary-manager.js} +3 -3
  177. package/server/dist/{project-code-discovery.js → modules/code/runtime/project-code-discovery.js} +2 -2
  178. package/server/dist/modules/conversations/domain/draft-stream.js +91 -0
  179. package/server/dist/modules/conversations/domain/recovery-context.js +101 -0
  180. package/server/dist/modules/conversations/index.js +10 -0
  181. package/server/dist/{chat-manager.js → modules/conversations/runtime/chat-manager.js} +32 -216
  182. package/server/dist/{context-budget.js → modules/conversations/runtime/context-budget.js} +1 -1
  183. package/server/dist/{explore-cwd-manager.js → modules/conversations/runtime/explore-cwd-manager.js} +1 -1
  184. package/server/dist/{explore-smash.js → modules/conversations/runtime/explore-smash.js} +1 -1
  185. package/server/dist/{explore-stdin-session.js → modules/conversations/runtime/explore-stdin-session.js} +1 -1
  186. package/server/dist/modules/delivery/adapters/decisions/chains.js +138 -0
  187. package/server/dist/modules/delivery/adapters/decisions/contracts.js +2 -0
  188. package/server/dist/modules/delivery/adapters/decisions/create.js +234 -0
  189. package/server/dist/modules/delivery/adapters/decisions/discard.js +251 -0
  190. package/server/dist/modules/delivery/adapters/decisions/dispatch.js +107 -0
  191. package/server/dist/modules/delivery/adapters/decisions/evidence.js +205 -0
  192. package/server/dist/modules/delivery/adapters/decisions/merge-local.js +338 -0
  193. package/server/dist/modules/delivery/adapters/decisions/metadata.js +109 -0
  194. package/server/dist/modules/delivery/adapters/decisions/observations.js +260 -0
  195. package/server/dist/modules/delivery/adapters/decisions/ownership.js +83 -0
  196. package/server/dist/modules/delivery/adapters/decisions/publish.js +242 -0
  197. package/server/dist/modules/delivery/adapters/decisions/recovery.js +425 -0
  198. package/server/dist/modules/delivery/adapters/decisions/retry.js +112 -0
  199. package/server/dist/modules/delivery/adapters/decisions/transitions.js +94 -0
  200. package/server/dist/modules/delivery/domain/decision-policy.js +50 -0
  201. package/server/dist/modules/delivery/domain/state.js +2 -0
  202. package/server/dist/modules/delivery/index.js +7 -0
  203. package/server/dist/{active-pr-continuation.js → modules/delivery/runtime/active-pr-continuation.js} +2 -2
  204. package/server/dist/{delivery-evidence.js → modules/delivery/runtime/delivery-evidence.js} +3 -3
  205. package/server/dist/{multi-repo-bases.js → modules/delivery/runtime/multi-repo-bases.js} +1 -1
  206. package/server/dist/{multi-repo-checkout.js → modules/delivery/runtime/multi-repo-checkout.js} +4 -4
  207. package/server/dist/{multi-repo-delivery.js → modules/delivery/runtime/multi-repo-delivery.js} +4 -4
  208. package/server/dist/{multi-repo-execution.js → modules/delivery/runtime/multi-repo-execution.js} +8 -8
  209. package/server/dist/{pr-body.js → modules/delivery/runtime/pr-body.js} +1 -1
  210. package/server/dist/{pr-follow-up-scope.js → modules/delivery/runtime/pr-follow-up-scope.js} +2 -2
  211. package/server/dist/{pr-follow-up.js → modules/delivery/runtime/pr-follow-up.js} +1 -1
  212. package/server/dist/{pr-naming.js → modules/delivery/runtime/pr-naming.js} +1 -1
  213. package/server/dist/{pr-publisher.js → modules/delivery/runtime/pr-publisher.js} +2 -2
  214. package/server/dist/{rail-isolated-launch.js → modules/delivery/runtime/rail-isolated-launch.js} +29 -27
  215. package/server/dist/{rail-launch-parser.js → modules/delivery/runtime/rail-launch-parser.js} +2 -2
  216. package/server/dist/{rail-merge-orchestrator.js → modules/delivery/runtime/rail-merge-orchestrator.js} +5 -5
  217. package/server/dist/modules/delivery/runtime/rail-pr-decision.js +12 -0
  218. package/server/dist/{rail-pr-delivery.js → modules/delivery/runtime/rail-pr-delivery.js} +1 -1
  219. package/server/dist/{rail-pr-store.js → modules/delivery/runtime/rail-pr-store.js} +2 -2
  220. package/server/dist/{rail-pr-ticket-effects.js → modules/delivery/runtime/rail-pr-ticket-effects.js} +3 -3
  221. package/server/dist/{rail-worktree-release.js → modules/delivery/runtime/rail-worktree-release.js} +4 -4
  222. package/server/dist/{rails-router.js → modules/delivery/runtime/rails-router.js} +66 -67
  223. package/server/dist/{review-packet.js → modules/delivery/runtime/review-packet.js} +3 -3
  224. package/server/dist/modules/execution/adapters/budget-storage.js +21 -0
  225. package/server/dist/modules/execution/adapters/usage-reader.js +38 -0
  226. package/server/dist/modules/execution/application/enforce-budget.js +14 -0
  227. package/server/dist/modules/execution/application/record-job-invocations.js +64 -0
  228. package/server/dist/modules/execution/application/recover-job-usage.js +200 -0
  229. package/server/dist/modules/execution/domain/job-accounting.js +2 -0
  230. package/server/dist/modules/execution/domain/scheduling.js +24 -0
  231. package/server/dist/modules/execution/domain/usage.js +21 -0
  232. package/server/dist/modules/execution/index.js +14 -0
  233. package/server/dist/modules/execution/ports.js +2 -0
  234. package/server/dist/{accept-ladder.js → modules/execution/runtime/accept-ladder.js} +1 -1
  235. package/server/dist/{interactive-job-session.js → modules/execution/runtime/interactive-job-session.js} +11 -11
  236. package/server/dist/{job-phase-breakdown.js → modules/execution/runtime/job-phase-breakdown.js} +1 -1
  237. package/server/dist/{queue-manager.js → modules/execution/runtime/queue-manager.js} +74 -491
  238. package/server/dist/{revision-seed.js → modules/execution/runtime/revision-seed.js} +1 -1
  239. package/server/dist/{spawn-lifecycle.js → modules/execution/runtime/spawn-lifecycle.js} +3 -3
  240. package/server/dist/{stuck-run-detector.js → modules/execution/runtime/stuck-run-detector.js} +1 -1
  241. package/server/dist/{loop-command-catalog.js → modules/loops/runtime/loop-command-catalog.js} +1 -1
  242. package/server/dist/{loop-executors.js → modules/loops/runtime/loop-executors.js} +17 -17
  243. package/server/dist/{loop-factory.js → modules/loops/runtime/loop-factory.js} +2 -21
  244. package/server/dist/{loop-graph.js → modules/loops/runtime/loop-graph.js} +25 -0
  245. package/server/dist/{loop-role-engines.js → modules/loops/runtime/loop-role-engines.js} +4 -4
  246. package/server/dist/{loop-run-manager.js → modules/loops/runtime/loop-run-manager.js} +101 -26
  247. package/server/dist/{loop-runs-store.js → modules/loops/runtime/loop-runs-store.js} +1 -1
  248. package/server/dist/{loop-shell-invocation.js → modules/loops/runtime/loop-shell-invocation.js} +2 -2
  249. package/server/dist/{loop-step-idle.js → modules/loops/runtime/loop-step-idle.js} +1 -1
  250. package/server/dist/{loop-templates.js → modules/loops/runtime/loop-templates.js} +24 -29
  251. package/server/dist/{loops-router.js → modules/loops/runtime/loops-router.js} +2 -2
  252. package/server/dist/{agent-chat-manager.js → modules/missions/runtime/agent-chat-manager.js} +19 -19
  253. package/server/dist/{agent-chat-router.js → modules/missions/runtime/agent-chat-router.js} +6 -6
  254. package/server/dist/{agent-context-resolver.js → modules/missions/runtime/agent-context-resolver.js} +8 -8
  255. package/server/dist/{agent-failure-briefing.js → modules/missions/runtime/agent-failure-briefing.js} +4 -2
  256. package/server/dist/{agent-fence-promotion.js → modules/missions/runtime/agent-fence-promotion.js} +1 -1
  257. package/server/dist/{agent-input-store.js → modules/missions/runtime/agent-input-store.js} +1 -1
  258. package/server/dist/{agent-operator-prompt.js → modules/missions/runtime/agent-operator-prompt.js} +75 -12
  259. package/server/dist/{agent-spec-framing.js → modules/missions/runtime/agent-spec-framing.js} +4 -4
  260. package/server/dist/{agent-steering.js → modules/missions/runtime/agent-steering.js} +1 -1
  261. package/server/dist/{mission-run-notify.js → modules/missions/runtime/mission-run-notify.js} +5 -2
  262. package/server/dist/modules/project-settings/adapters/http.js +24 -0
  263. package/server/dist/modules/project-settings/adapters/sqlite.js +120 -0
  264. package/server/dist/modules/project-settings/application.js +11 -0
  265. package/server/dist/modules/project-settings/domain.js +95 -0
  266. package/server/dist/modules/project-settings/index.js +11 -0
  267. package/server/dist/modules/project-settings/ports.js +2 -0
  268. package/server/dist/{contract-refine-runner.js → modules/specs/runtime/contract-refine-runner.js} +12 -12
  269. package/server/dist/{proposal-manager.js → modules/specs/runtime/proposal-manager.js} +8 -8
  270. package/server/dist/{smash-runner.js → modules/specs/runtime/smash-runner.js} +26 -58
  271. package/server/dist/{spec-addenda-core.js → modules/specs/runtime/spec-addenda-core.js} +2 -2
  272. package/server/dist/{spec-addenda.js → modules/specs/runtime/spec-addenda.js} +3 -3
  273. package/server/dist/{spec-launcher-manager.js → modules/specs/runtime/spec-launcher-manager.js} +8 -8
  274. package/server/dist/{spec-models.js → modules/specs/runtime/spec-models.js} +1 -1
  275. package/server/dist/{ticket-watcher.js → modules/specs/runtime/ticket-watcher.js} +1 -1
  276. package/server/dist/{background-process-control.js → modules/terminals/runtime/background-process-control.js} +1 -1
  277. package/server/dist/{background-process-service.js → modules/terminals/runtime/background-process-service.js} +3 -3
  278. package/server/dist/{background-process-store.js → modules/terminals/runtime/background-process-store.js} +1 -1
  279. package/server/dist/{background-windows-bootstrap.js → modules/terminals/runtime/background-windows-bootstrap.js} +3 -3
  280. package/server/dist/{terminal-manager.js → modules/terminals/runtime/terminal-manager.js} +3 -3
  281. package/server/dist/project-git.js +1 -1
  282. package/server/dist/project-profile-support.js +32 -0
  283. package/server/dist/project-registry.js +34 -40
  284. package/server/dist/project-router-background-processes.js +1 -1
  285. package/server/dist/project-router-chat.js +6 -6
  286. package/server/dist/project-router-git.js +1 -1
  287. package/server/dist/project-router-helpers.js +2 -2
  288. package/server/dist/project-router-jobs.js +14 -12
  289. package/server/dist/project-router-loop-runs.js +12 -12
  290. package/server/dist/project-router-settings.js +15 -75
  291. package/server/dist/project-router-setup.js +2 -2
  292. package/server/dist/project-router-spending.js +4 -4
  293. package/server/dist/project-router-terminals.js +4 -4
  294. package/server/dist/project-router-tickets.js +14 -14
  295. package/server/dist/project-router.js +13 -13
  296. package/server/dist/providers/claude-adapter.js +3 -2
  297. package/server/dist/providers/codex-adapter.js +3 -3
  298. package/server/dist/providers/gemini-adapter.js +1 -1
  299. package/server/dist/providers/telemetry-env.js +55 -0
  300. package/server/dist/runtime-role-prompts-router.js +2 -2
  301. package/server/dist/setup-manager.js +2 -48
  302. package/server/dist/shared/git-branch-name.js +16 -0
  303. package/server/dist/transient-children.js +3 -3
  304. package/server/dist/util/distribute-int.js +33 -0
  305. package/client/dist/assets/ReviewPacketPage-D-UjTef3.js +0 -4
  306. package/client/dist/assets/index-BAtqmAZR.css +0 -2
  307. package/client/dist/assets/packet-CjS_478C.js +0 -1
  308. package/client/dist/assets/packet-D69dKsHN.js +0 -1
  309. package/client/dist/assets/packet-D9rU6Oxo.js +0 -1
  310. package/client/dist/assets/packet-DMDFoamg.js +0 -1
  311. package/client/dist/assets/packet-Dd2RMs1h.js +0 -1
  312. package/client/dist/assets/packet-DjC9OibC.js +0 -1
  313. package/client/dist/assets/packet-DwPtJoDz.js +0 -1
  314. package/client/dist/assets/packet-ceahDg8_.js +0 -1
  315. package/server/dist/rail-pr-decision.js +0 -2377
  316. package/server/dist/ticket-broadcast.js +0 -47
  317. /package/server/dist/{ai-invocations.js → modules/accounting/runtime/ai-invocations.js} +0 -0
  318. /package/server/dist/{codex-otel-bridge.js → modules/accounting/runtime/codex-otel-bridge.js} +0 -0
  319. /package/server/dist/{metrics.js → modules/accounting/runtime/metrics.js} +0 -0
  320. /package/server/dist/{telemetry-export.js → modules/accounting/runtime/telemetry-export.js} +0 -0
  321. /package/server/dist/{agent-runtime-accounting.js → modules/agent-runtime/runtime/agent-runtime-accounting.js} +0 -0
  322. /package/server/dist/{agent-runtime-events.js → modules/agent-runtime/runtime/agent-runtime-events.js} +0 -0
  323. /package/server/dist/{agent-runtime-history.js → modules/agent-runtime/runtime/agent-runtime-history.js} +0 -0
  324. /package/server/dist/{agent-runtime-metrics.js → modules/agent-runtime/runtime/agent-runtime-metrics.js} +0 -0
  325. /package/server/dist/{agent-runtime-package.js → modules/agent-runtime/runtime/agent-runtime-package.js} +0 -0
  326. /package/server/dist/{agent-runtime-repositories.js → modules/agent-runtime/runtime/agent-runtime-repositories.js} +0 -0
  327. /package/server/dist/{agent-runtime-verification-suggestions.js → modules/agent-runtime/runtime/agent-runtime-verification-suggestions.js} +0 -0
  328. /package/server/dist/{agent-refine-db.js → modules/agents/runtime/agent-refine-db.js} +0 -0
  329. /package/server/dist/{browser-capture-types.js → modules/browser/runtime/browser-capture-types.js} +0 -0
  330. /package/server/dist/{browser-context-pool.js → modules/browser/runtime/browser-context-pool.js} +0 -0
  331. /package/server/dist/{browser-network.js → modules/browser/runtime/browser-network.js} +0 -0
  332. /package/server/dist/{browser-viewport.js → modules/browser/runtime/browser-viewport.js} +0 -0
  333. /package/server/dist/{blueprint-render.js → modules/builder/runtime/blueprint-render.js} +0 -0
  334. /package/server/dist/{blueprint-spec-fixtures.js → modules/builder/runtime/blueprint-spec-fixtures.js} +0 -0
  335. /package/server/dist/{blueprint-store.js → modules/builder/runtime/blueprint-store.js} +0 -0
  336. /package/server/dist/{blueprint-types.js → modules/builder/runtime/blueprint-types.js} +0 -0
  337. /package/server/dist/{builder-cwd-manager.js → modules/builder/runtime/builder-cwd-manager.js} +0 -0
  338. /package/server/dist/{milestone-chain-store.js → modules/builder/runtime/milestone-chain-store.js} +0 -0
  339. /package/server/dist/{changes-reader.js → modules/code/runtime/changes-reader.js} +0 -0
  340. /package/server/dist/{context-scope.js → modules/conversations/runtime/context-scope.js} +0 -0
  341. /package/server/dist/{explore-contract-refine.js → modules/conversations/runtime/explore-contract-refine.js} +0 -0
  342. /package/server/dist/{explore-draft-title.js → modules/conversations/runtime/explore-draft-title.js} +0 -0
  343. /package/server/dist/{merge-manager.js → modules/delivery/runtime/merge-manager.js} +0 -0
  344. /package/server/dist/{multi-repo-execution-store.js → modules/delivery/runtime/multi-repo-execution-store.js} +0 -0
  345. /package/server/dist/{pr-lifecycle.js → modules/delivery/runtime/pr-lifecycle.js} +0 -0
  346. /package/server/dist/{rail-isolation.js → modules/delivery/runtime/rail-isolation.js} +0 -0
  347. /package/server/dist/{rail-pr-recovery-git.js → modules/delivery/runtime/rail-pr-recovery-git.js} +0 -0
  348. /package/server/dist/{rail-worktrees-store.js → modules/delivery/runtime/rail-worktrees-store.js} +0 -0
  349. /package/server/dist/{rails-store.js → modules/delivery/runtime/rails-store.js} +0 -0
  350. /package/server/dist/{job-listing.js → modules/execution/runtime/job-listing.js} +0 -0
  351. /package/server/dist/{job-spawn-idempotency.js → modules/execution/runtime/job-spawn-idempotency.js} +0 -0
  352. /package/server/dist/{run-duration-stats.js → modules/execution/runtime/run-duration-stats.js} +0 -0
  353. /package/server/dist/{verification-sentinel.js → modules/execution/runtime/verification-sentinel.js} +0 -0
  354. /package/server/dist/{loop-constants.js → modules/loops/runtime/loop-constants.js} +0 -0
  355. /package/server/dist/{loop-decider.js → modules/loops/runtime/loop-decider.js} +0 -0
  356. /package/server/dist/{loop-effect.js → modules/loops/runtime/loop-effect.js} +0 -0
  357. /package/server/dist/{loop-preview.js → modules/loops/runtime/loop-preview.js} +0 -0
  358. /package/server/dist/{loop-templates-ported.js → modules/loops/runtime/loop-templates-ported.js} +0 -0
  359. /package/server/dist/{loops-store.js → modules/loops/runtime/loops-store.js} +0 -0
  360. /package/server/dist/{agent-chat-registry.js → modules/missions/runtime/agent-chat-registry.js} +0 -0
  361. /package/server/dist/{agent-cwd-manager.js → modules/missions/runtime/agent-cwd-manager.js} +0 -0
  362. /package/server/dist/{agent-tier.js → modules/missions/runtime/agent-tier.js} +0 -0
  363. /package/server/dist/{spec-contract-prompt.js → modules/specs/runtime/spec-contract-prompt.js} +0 -0
  364. /package/server/dist/{spec-draft-parser.js → modules/specs/runtime/spec-draft-parser.js} +0 -0
  365. /package/server/dist/{ticket-store.js → modules/specs/runtime/ticket-store.js} +0 -0
  366. /package/server/dist/{terminal-marks-store.js → modules/terminals/runtime/terminal-marks-store.js} +0 -0
  367. /package/server/dist/{terminal-osc-parser.js → modules/terminals/runtime/terminal-osc-parser.js} +0 -0
  368. /package/server/dist/{terminal-settings.js → modules/terminals/runtime/terminal-settings.js} +0 -0
@@ -6,56 +6,56 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.prDeliveryRevisionAllowed = prDeliveryRevisionAllowed;
7
7
  exports.createRailsRouter = createRailsRouter;
8
8
  const pr_follow_up_1 = require("./pr-follow-up");
9
- const agent_runtime_settings_1 = require("./agent-runtime-settings");
9
+ const agent_runtime_settings_1 = require("../../agent-runtime/runtime/agent-runtime-settings");
10
10
  const path_1 = __importDefault(require("path"));
11
11
  const express_1 = require("express");
12
12
  const rails_store_1 = require("./rails-store");
13
- const queue_manager_1 = require("./queue-manager");
14
- const provider_selection_1 = require("./provider-selection");
15
- const feature_flags_1 = require("./feature-flags");
16
- const file_provenance_1 = require("./file-provenance");
17
- const file_story_1 = require("./file-story");
18
- const loops_store_1 = require("./loops-store");
19
- const loop_runs_store_1 = require("./loop-runs-store");
20
- const registry_1 = require("./providers/registry");
21
- const providers_1 = require("./providers");
22
- const loop_role_engines_1 = require("./loop-role-engines");
23
- const runtime_1 = require("./providers/runtime");
24
- const agent_defaults_1 = require("./agent-defaults");
25
- const profile_manager_1 = require("./profile-manager");
26
- const spec_models_1 = require("./spec-models");
27
- const workspace_resolution_1 = require("./workspace-resolution");
28
- const loop_factory_1 = require("./loop-factory");
29
- const loop_constants_1 = require("./loop-constants");
30
- const loop_command_catalog_1 = require("./loop-command-catalog");
31
- const loop_graph_1 = require("./loop-graph");
13
+ const queue_manager_1 = require("../../execution/runtime/queue-manager");
14
+ const provider_selection_1 = require("../../../provider-selection");
15
+ const feature_flags_1 = require("../../../feature-flags");
16
+ const file_provenance_1 = require("../../code/runtime/file-provenance");
17
+ const file_story_1 = require("../../code/runtime/file-story");
18
+ const loops_store_1 = require("../../loops/runtime/loops-store");
19
+ const loop_runs_store_1 = require("../../loops/runtime/loop-runs-store");
20
+ const registry_1 = require("../../../providers/registry");
21
+ const providers_1 = require("../../../providers");
22
+ const loop_role_engines_1 = require("../../loops/runtime/loop-role-engines");
23
+ const runtime_1 = require("../../../providers/runtime");
24
+ const agent_defaults_1 = require("../../agents/runtime/agent-defaults");
25
+ const profile_manager_1 = require("../../agents/runtime/profile-manager");
26
+ const spec_models_1 = require("../../specs/runtime/spec-models");
27
+ const workspace_resolution_1 = require("../../../workspace-resolution");
28
+ const loop_factory_1 = require("../../loops/runtime/loop-factory");
29
+ const loop_constants_1 = require("../../loops/runtime/loop-constants");
30
+ const loop_command_catalog_1 = require("../../loops/runtime/loop-command-catalog");
31
+ const loop_graph_1 = require("../../loops/runtime/loop-graph");
32
32
  const rail_isolation_1 = require("./rail-isolation");
33
33
  const rail_pr_store_1 = require("./rail-pr-store");
34
- const loop_effect_1 = require("./loop-effect");
34
+ const loop_effect_1 = require("../../loops/runtime/loop-effect");
35
35
  const review_packet_1 = require("./review-packet");
36
36
  const delivery_evidence_1 = require("./delivery-evidence");
37
- const accept_ladder_1 = require("./accept-ladder");
37
+ const accept_ladder_1 = require("../../execution/runtime/accept-ladder");
38
38
  const rail_pr_decision_1 = require("./rail-pr-decision");
39
39
  const active_pr_continuation_1 = require("./active-pr-continuation");
40
40
  const rail_isolated_launch_1 = require("./rail-isolated-launch");
41
- const worktree_manager_1 = require("./worktree-manager");
42
- const integration_branch_1 = require("./integration-branch");
41
+ const worktree_manager_1 = require("../../../worktree-manager");
42
+ const integration_branch_1 = require("../../../integration-branch");
43
43
  const rail_worktree_release_1 = require("./rail-worktree-release");
44
- const project_git_1 = require("./project-git");
44
+ const project_git_1 = require("../../../project-git");
45
45
  const pr_publisher_1 = require("./pr-publisher");
46
- const project_repositories_1 = require("./project-repositories");
46
+ const project_repositories_1 = require("../../../project-repositories");
47
47
  const multi_repo_checkout_1 = require("./multi-repo-checkout");
48
48
  const multi_repo_bases_1 = require("./multi-repo-bases");
49
49
  const multi_repo_execution_1 = require("./multi-repo-execution");
50
50
  const multi_repo_execution_store_1 = require("./multi-repo-execution-store");
51
- const ids_1 = require("./ids");
52
- const repo_lock_1 = require("./repo-lock");
53
- const agent_chat_registry_1 = require("./agent-chat-registry");
54
- const mission_run_notify_1 = require("./mission-run-notify");
55
- const agent_runtime_controls_router_1 = require("./agent-runtime-controls-router");
56
- const ticket_store_1 = require("./ticket-store");
57
- const spec_addenda_1 = require("./spec-addenda");
58
- const process_admission_1 = require("./process-admission");
51
+ const ids_1 = require("../../../ids");
52
+ const repo_lock_1 = require("../../../repo-lock");
53
+ const agent_chat_registry_1 = require("../../missions/runtime/agent-chat-registry");
54
+ const mission_run_notify_1 = require("../../missions/runtime/mission-run-notify");
55
+ const agent_runtime_controls_router_1 = require("../../agent-runtime/runtime/agent-runtime-controls-router");
56
+ const ticket_store_1 = require("../../specs/runtime/ticket-store");
57
+ const spec_addenda_1 = require("../../specs/runtime/spec-addenda");
58
+ const process_admission_1 = require("../../../process-admission");
59
59
  const VALID_MODES = new Set(['implement', 'batch-implement', 'freestyle', 'loop']);
60
60
  function prDeliveryContinuesTickets(delivery, ticketIds) {
61
61
  if (delivery.decision !== 'pr_draft' && delivery.decision !== 'pr_ready')
@@ -562,18 +562,7 @@ function createRailsRouter() {
562
562
  res.status(404).json({ error: 'Factory loop not found' });
563
563
  return;
564
564
  }
565
- // The revision loop is meaningless without a revision to apply: its prompt
566
- // consumes {{const:REVISION_REQUEST}}, and an unresolved constant renders
567
- // as an EMPTY string (loop-constants), so naming it directly would spawn a
568
- // run whose central instruction is silently blank. It is reachable by id
569
- // (fork/preview resolve it), so the launch door has to refuse it.
570
- if (loopId === loop_factory_1.FACTORY_REVISION_LOOP_ID && !revisionOfDeliveryId) {
571
- res.status(400).json({
572
- error: 'revision_loop_requires_revision',
573
- detail: 'factory:revision only runs as a revision — pass revisionOfDeliveryId and revisionNote instead of naming the loop',
574
- });
575
- return;
576
- }
565
+ loopId = (0, loop_factory_1.getFactoryLoop)(loopId).id; // canonicalize saved legacy aliases
577
566
  mode = fmode;
578
567
  }
579
568
  if (!VALID_MODES.has(mode)) {
@@ -589,16 +578,10 @@ function createRailsRouter() {
589
578
  if ((0, feature_flags_1.isLoopsEnabled)() && (typeof loopId !== 'string' || !loopId) && mode !== 'loop') {
590
579
  loopId = (0, loop_factory_1.factoryLoopForMode)(mode)?.id;
591
580
  }
592
- // A revision must run the Architect-LESS revision loop, whatever the rail's
593
- // stored mode is. Without this every one-sentence tweak would re-run the
594
- // full implement pipeline — the exact cost the feature exists to avoid.
595
- // An explicit loopId is respected (a caller naming a loop means it).
596
- if (revisionOfDeliveryId && (0, feature_flags_1.isLoopsEnabled)() && (typeof loopId !== 'string' || !loopId || (0, loop_factory_1.isFactoryLoopId)(loopId))) {
597
- const revisionLoop = (0, loop_factory_1.getFactoryLoop)(loop_factory_1.FACTORY_REVISION_LOOP_ID);
598
- if (revisionLoop) {
599
- loopId = revisionLoop.id;
600
- mode = revisionLoop.mode;
601
- }
581
+ // Delivery continuation always uses Quick SDD; the old Revision loop is retired.
582
+ if (revisionOfDeliveryId && (0, feature_flags_1.isLoopsEnabled)()) {
583
+ loopId = 'factory:sdd-quick-openspec';
584
+ mode = 'loop';
602
585
  }
603
586
  if (mode === 'loop' && !(0, feature_flags_1.isLoopsEnabled)()) {
604
587
  res.status(403).json({ error: 'Loops are disabled on this server' });
@@ -635,6 +618,13 @@ function createRailsRouter() {
635
618
  res.status(400).json({ error: 'Rail has no tickets assigned' });
636
619
  return;
637
620
  }
621
+ // The durable delta chooses Quick SDD regardless of stale rail/agent defaults.
622
+ // Revision is a delivery-continuation mechanism, not the implementation loop.
623
+ const launchAddenda = (0, spec_addenda_1.planSpecAddendaAt)((0, spec_addenda_1.ticketStorePathForProject)(c.project), rail.ticketIds);
624
+ if (launchAddenda.length && (0, feature_flags_1.isLoopsEnabled)()) {
625
+ loopId = 'factory:sdd-quick-openspec';
626
+ mode = 'loop';
627
+ }
638
628
  let repositoryIds;
639
629
  const primaryRepository = (0, project_repositories_1.getProjectRepositories)(c.project).find((repository) => repository.isPrimary);
640
630
  try {
@@ -954,13 +944,19 @@ function createRailsRouter() {
954
944
  }
955
945
  }
956
946
  const pendingSnapshot = pending ? (0, rail_pr_store_1.toPrDeliverySnapshot)(pending) : null;
957
- // A revision is the ONE launch allowed to proceed against an
958
- // undecided delivery, and only on the exact terms below: the caller
959
- // names that delivery AND covers its full ticket set. Anything else
960
- // would silently append work to branches the user has not judged.
947
+ if (revisionOfDeliveryId && !pendingSnapshot) {
948
+ res.status(409).json({ error: 'invalid_revision_target', detail: 'The delivery is no longer active; refresh before continuing.' });
949
+ return;
950
+ }
951
+ // Continue only the exact active generation and its full spec set.
952
+ // Explicit change requests name it; open addenda on the same rail
953
+ // identify it implicitly. Both use the existing supersession contract.
961
954
  const revisionsEnabled = (0, feature_flags_1.areDeliveryRevisionsEnabled)();
962
- const revisionOfPending = Boolean(revisionsEnabled && pendingSnapshot && revisionOfDeliveryId
963
- && prDeliveryRevisionAllowed(pendingSnapshot, revisionOfDeliveryId, rail.ticketIds));
955
+ const addendumContinuation = Boolean(launchAddenda.length && pendingSnapshot && pendingSnapshot.decision !== 'building'
956
+ && !revisionOfDeliveryId
957
+ && prDeliveryRevisionAllowed(pendingSnapshot, pendingSnapshot.id, rail.ticketIds));
958
+ const revisionOfPending = Boolean(revisionsEnabled && pendingSnapshot && (addendumContinuation || (revisionOfDeliveryId
959
+ && prDeliveryRevisionAllowed(pendingSnapshot, revisionOfDeliveryId, rail.ticketIds))));
964
960
  if (revisionsEnabled && pendingSnapshot && revisionOfDeliveryId && !revisionOfPending) {
965
961
  res.status(409).json({
966
962
  error: 'invalid_revision_target',
@@ -977,14 +973,17 @@ function createRailsRouter() {
977
973
  revisionRequest = {
978
974
  ofDeliveryId: pendingSnapshot.id,
979
975
  decision: pendingSnapshot.decision,
980
- note: revisionNote,
976
+ note: addendumContinuation
977
+ ? `Implement the attached spec addenda only: ${launchAddenda.flatMap((entry) => entry.addenda.map((a) => `#${entry.ticketId} [${a.id}] ${a.title}`)).join('; ')}. Their complete frozen bodies are in SPEC ADDENDA; preserve existing behavior outside that scope.`
978
+ : revisionNote,
981
979
  };
982
980
  }
983
981
  // Explicit target vs an undecided continuable delivery: the slot's
984
982
  // active generation owns its PR. A DIFFERENT explicit target would
985
983
  // append to the undecided branches → 409; the SAME PR is redundant
986
984
  // (the continuation contract below already drives it) and is dropped.
987
- if (pendingSnapshot && typeof targetPrNumber === 'number' && pendingSnapshot.prNumber !== targetPrNumber) {
985
+ if (pendingSnapshot && typeof targetPrNumber === 'number' && pendingSnapshot.prNumber !== targetPrNumber
986
+ && !pendingSnapshot.repositoryDeliveries?.some((delivery) => delivery.prNumber === targetPrNumber)) {
988
987
  res.status(409).json({ error: 'pr_decision_pending', prDeliveryId: pendingSnapshot.id });
989
988
  return;
990
989
  }
@@ -1067,7 +1066,7 @@ function createRailsRouter() {
1067
1066
  originConversationId: originConversationId ?? null,
1068
1067
  ...(baseBranch ? { baseBranch } : {}),
1069
1068
  ...(continuablePrDelivery?.executionManifest && !revisionRequest ? { repositoryContinuation: { deliveryId: continuablePrDelivery.id, decision: continuablePrDelivery.decision } } : {}),
1070
- ...(continuablePrDelivery && !continuablePrDelivery.executionManifest ? {
1069
+ ...(continuablePrDelivery && !continuablePrDelivery.executionManifest && prDeliveryContinuesTickets(continuablePrDelivery, rail.ticketIds) ? {
1071
1070
  requiredPrContinuation: {
1072
1071
  deliveryId: continuablePrDelivery.id,
1073
1072
  decision: continuablePrDelivery.decision,
@@ -1089,7 +1088,7 @@ function createRailsRouter() {
1089
1088
  ...(revisionRequest ? { revision: revisionRequest } : {}),
1090
1089
  ...(followUp ? { followUp } : {}),
1091
1090
  });
1092
- res.status(202).json({ loopRunIds: ids, railIndex, mode, isolated: true, ...(followUp ? { followUp: { id: followUp.id, version: followUp.version, hash: followUp.hash } } : {}) });
1091
+ res.status(202).json({ loopRunIds: ids, railIndex, mode, loopId, prDeliveryId: (0, rail_pr_store_1.getActivePrDeliveryByRail)(c.db, railIndex)?.id ?? null, isolated: true, ...(followUp ? { followUp: { id: followUp.id, version: followUp.version, hash: followUp.hash } } : {}) });
1093
1092
  return;
1094
1093
  }
1095
1094
  catch (err) {
@@ -1770,4 +1769,4 @@ function createRailsRouter() {
1770
1769
  });
1771
1770
  return router;
1772
1771
  }
1773
- const agent_runtime_controls_router_2 = require("./agent-runtime-controls-router");
1772
+ const agent_runtime_controls_router_2 = require("../../agent-runtime/runtime/agent-runtime-controls-router");
@@ -35,12 +35,12 @@ exports.packetHasUnsourcedNumericClaim = packetHasUnsourcedNumericClaim;
35
35
  * FILES changed, which is all the diff can actually prove.
36
36
  */
37
37
  const pr_follow_up_1 = require("./pr-follow-up");
38
- const spec_addenda_core_1 = require("./spec-addenda-core");
38
+ const spec_addenda_core_1 = require("../../specs/runtime/spec-addenda-core");
39
39
  const delivery_evidence_1 = require("./delivery-evidence");
40
40
  const rail_pr_store_1 = require("./rail-pr-store");
41
41
  const pr_body_1 = require("./pr-body");
42
- const ai_invocations_1 = require("./ai-invocations");
43
- const project_repository_provenance_1 = require("./project-repository-provenance");
42
+ const ai_invocations_1 = require("../../accounting/runtime/ai-invocations");
43
+ const project_repository_provenance_1 = require("../../../project-repository-provenance");
44
44
  const TEST_FILE_RE = /(\.test\.|\.spec\.|(^|\/)__tests__\/)/;
45
45
  function churnForRuns(db, runIds, repository) {
46
46
  const ids = [...new Set(runIds.filter((id) => typeof id === 'string' && id.length > 0))];
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createQueueBudgetStorage = createQueueBudgetStorage;
4
+ function createQueueBudgetStorage(db) {
5
+ return {
6
+ project(projectId, dayStart) {
7
+ const row = db.prepare(`SELECT value FROM queue_state WHERE key = 'config.daily_budget_usd'`).get();
8
+ if (!row || !projectId)
9
+ return null;
10
+ const budget = parseFloat(row.value);
11
+ if (!(budget > 0))
12
+ return null;
13
+ const spend = db.prepare(`SELECT COALESCE(SUM(total_cost_usd), 0) as total FROM ai_invocations
14
+ WHERE project_id = ? AND total_cost_usd IS NOT NULL AND started_at >= ?`).get(projectId, dayStart());
15
+ return { budget, totalSpend: spend.total };
16
+ },
17
+ pause() {
18
+ db.prepare(`INSERT OR REPLACE INTO queue_state (key, value) VALUES ('paused', 'true')`).run();
19
+ },
20
+ };
21
+ }
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createDurableUsageReader = createDurableUsageReader;
4
+ const runtime_1 = require("../../../providers/runtime");
5
+ const result_event_1 = require("../../accounting/runtime/result-event");
6
+ /** Project-bound SQLite/provider adapter; never starts a transaction or buffers all events. */
7
+ function createDurableUsageReader(db, jobId, adapter) {
8
+ return {
9
+ events(mode, afterSeq) {
10
+ if (mode === 'results')
11
+ return db.prepare(`
12
+ SELECT seq, event_type, payload FROM events
13
+ WHERE job_id = ? AND source = 'stdout' AND event_type = 'result'
14
+ ORDER BY seq, id
15
+ `).iterate(jobId);
16
+ if (mode === 'tail')
17
+ return db.prepare(`
18
+ SELECT seq, event_type, payload FROM events
19
+ WHERE job_id = ? AND source = 'stdout' AND event_type != 'log' AND seq > ?
20
+ ORDER BY seq, id
21
+ `).iterate(jobId, afterSeq);
22
+ return db.prepare(`
23
+ SELECT seq, event_type, payload FROM events
24
+ WHERE job_id = ? AND source = 'stdout' AND event_type != 'log'
25
+ ORDER BY seq, id
26
+ `).iterate(jobId);
27
+ },
28
+ parse: payload => (0, runtime_1.parseStreamEvents)(adapter, payload),
29
+ normalize: (event, fallbackModel) => (0, result_event_1.finaliseInvocationResult)(adapter, [event], { fallbackModel }),
30
+ messageId(event) {
31
+ const raw = event.kind === 'other' ? event.raw : null;
32
+ const message = raw && typeof raw.message === 'object' && raw.message
33
+ ? raw.message : null;
34
+ return event.messageId ?? (message && typeof message.id === 'string' ? message.id : undefined);
35
+ },
36
+ malformedEvent: error => console.warn(`[queue-manager] ignored malformed durable event for ${jobId}:`, error),
37
+ };
38
+ }
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.enforceDailyBudgets = enforceDailyBudgets;
4
+ /** Project admission is evaluated first; storage failures abort later effects. */
5
+ function enforceDailyBudgets(ports) {
6
+ const enforce = (scope, snapshot) => {
7
+ if (snapshot?.budget != null && snapshot.budget > 0 && snapshot.totalSpend >= snapshot.budget) {
8
+ ports.exceeded(scope, { ...snapshot, budget: snapshot.budget });
9
+ }
10
+ };
11
+ enforce('project', ports.project());
12
+ if (ports.desktop)
13
+ enforce('desktop', ports.desktop());
14
+ }
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.recordJobInvocations = recordJobInvocations;
4
+ const distribute_int_1 = require("../../../util/distribute-int");
5
+ /** Preserve total integer usage and stable replay references across ticket attribution. */
6
+ function recordJobInvocations(projectId, params, ports) {
7
+ const { jobId, provider, status, startedAt, finishedAt, ticketIds, estimated, result } = params;
8
+ // Single-ticket / no-ticket: one row, plain jobId (byte-compatible).
9
+ if (ticketIds.length <= 1) {
10
+ ports.write({
11
+ id: ports.newId(),
12
+ project_id: projectId,
13
+ provider,
14
+ surface: 'job',
15
+ surface_ref_id: jobId,
16
+ ticket_id: ticketIds[0] ?? null,
17
+ conversation_id: params.conversationId ?? null,
18
+ status,
19
+ started_at: startedAt,
20
+ finished_at: finishedAt,
21
+ total_cost_usd_estimated: estimated,
22
+ ...result,
23
+ });
24
+ return [jobId];
25
+ }
26
+ // Multi-ticket: split across one row per ticket. Cost & duration split evenly
27
+ // as floats; token & turn totals via largest-remainder (sum exactly to total).
28
+ const n = ticketIds.length;
29
+ const evenSplit = (v) => v === undefined ? undefined : v / n;
30
+ const tokensIn = (0, distribute_int_1.distributeIntEvenly)(result.tokens_in, n);
31
+ const tokensOut = (0, distribute_int_1.distributeIntEvenly)(result.tokens_out, n);
32
+ const cacheRead = (0, distribute_int_1.distributeIntEvenly)(result.tokens_cache_read, n);
33
+ const cacheCreate = (0, distribute_int_1.distributeIntEvenly)(result.tokens_cache_create, n);
34
+ const numTurns = (0, distribute_int_1.distributeIntEvenly)(result.num_turns, n);
35
+ const refIds = [];
36
+ ticketIds.forEach((ticketId, i) => {
37
+ const refId = `${jobId}#t${ticketId}`;
38
+ refIds.push(refId);
39
+ ports.write({
40
+ id: ports.newId(),
41
+ project_id: projectId,
42
+ provider,
43
+ surface: 'job',
44
+ surface_ref_id: refId,
45
+ ticket_id: ticketId,
46
+ conversation_id: params.conversationId ?? null,
47
+ status,
48
+ started_at: startedAt,
49
+ finished_at: finishedAt,
50
+ total_cost_usd_estimated: estimated,
51
+ tokens_in: tokensIn[i],
52
+ tokens_out: tokensOut[i],
53
+ tokens_cache_read: cacheRead[i],
54
+ tokens_cache_create: cacheCreate[i],
55
+ total_cost_usd: evenSplit(result.total_cost_usd),
56
+ num_turns: numTurns[i],
57
+ model: result.model,
58
+ session_id: result.session_id,
59
+ duration_ms: evenSplit(result.duration_ms),
60
+ duration_api_ms: evenSplit(result.duration_api_ms),
61
+ });
62
+ });
63
+ return refIds;
64
+ }
@@ -0,0 +1,200 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.recoverJobUsage = recoverJobUsage;
4
+ const usage_1 = require("../domain/usage");
5
+ /** Rebuild usage from ordered durable evidence without loading a transcript into memory. */
6
+ function recoverJobUsage(ports, fallbackModel, interactive) {
7
+ const parse = (row) => {
8
+ try {
9
+ return ports.parse(row.payload);
10
+ }
11
+ catch (error) {
12
+ ports.malformedEvent(error);
13
+ return [];
14
+ }
15
+ };
16
+ const makeUsageAccumulator = () => {
17
+ const totals = {
18
+ tokens_in: 0,
19
+ tokens_out: 0,
20
+ tokens_cache_read: 0,
21
+ tokens_cache_create: 0,
22
+ total_cost_usd: 0,
23
+ num_turns: 0,
24
+ duration_ms: 0,
25
+ duration_api_ms: 0,
26
+ };
27
+ let model = fallbackModel ?? undefined;
28
+ let sessionId;
29
+ let estimated = false;
30
+ const snapshots = new Map();
31
+ const MAX_SNAPSHOT_KEYS = 4_096;
32
+ const add = (event, seq) => {
33
+ const finalised = ports.normalize(event, model);
34
+ const result = (0, usage_1.sanitizeRecoveredResult)(finalised.result);
35
+ const messageId = ports.messageId(event);
36
+ const stableId = messageId ? `message:${messageId}` : `${event.kind}:${seq}`;
37
+ const previous = snapshots.get(stableId) ?? {};
38
+ const addDelta = (key) => {
39
+ const current = result[key];
40
+ if (typeof current !== 'number')
41
+ return;
42
+ const prior = previous[key];
43
+ totals[key] += Math.max(0, current - (typeof prior === 'number' ? prior : 0));
44
+ };
45
+ addDelta('tokens_in');
46
+ addDelta('tokens_out');
47
+ addDelta('tokens_cache_read');
48
+ addDelta('tokens_cache_create');
49
+ addDelta('total_cost_usd');
50
+ addDelta('num_turns');
51
+ addDelta('duration_ms');
52
+ addDelta('duration_api_ms');
53
+ model = result.model ?? model;
54
+ sessionId = result.session_id ?? sessionId;
55
+ estimated = estimated || finalised.estimated;
56
+ if (!snapshots.has(stableId) && snapshots.size >= MAX_SNAPSHOT_KEYS) {
57
+ snapshots.delete(snapshots.keys().next().value);
58
+ }
59
+ // Frames for one provider message are contiguous; retain a bounded LRU
60
+ // of recent snapshots for retransmission/delta dedupe without letting a
61
+ // malicious transcript allocate one map entry per event forever.
62
+ snapshots.delete(stableId);
63
+ snapshots.set(stableId, { ...previous, ...result });
64
+ };
65
+ const result = () => {
66
+ const hasUsage = Object.values(totals).some((value) => value > 0);
67
+ return {
68
+ result: hasUsage ? { ...totals, model, session_id: sessionId } : {},
69
+ estimated,
70
+ };
71
+ };
72
+ return { add, result };
73
+ };
74
+ if (!interactive) {
75
+ const accumulator = makeUsageAccumulator();
76
+ let lastValidResult = null;
77
+ const events = ports.events('all');
78
+ for (const row of events) {
79
+ for (const event of parse(row)) {
80
+ if (event.kind === 'result') {
81
+ const finalised = ports.normalize(event, fallbackModel ?? undefined);
82
+ lastValidResult = {
83
+ ...finalised,
84
+ result: (0, usage_1.sanitizeRecoveredResult)(finalised.result),
85
+ };
86
+ }
87
+ else {
88
+ accumulator.add(event, row.seq);
89
+ }
90
+ }
91
+ }
92
+ const fallback = accumulator.result();
93
+ if (lastValidResult) {
94
+ const result = { ...fallback.result };
95
+ for (const [key, value] of Object.entries(lastValidResult.result)) {
96
+ // Provider normalisers intentionally retain optional keys with an
97
+ // undefined value. Only concrete terminal fields are authoritative;
98
+ // an omitted field must not erase recoverable assistant evidence.
99
+ if (value !== undefined) {
100
+ result[key] = value;
101
+ }
102
+ }
103
+ return {
104
+ result,
105
+ // A native terminal cost is authoritative. When the terminal frame
106
+ // omits cost, preserve whether the assistant-frame backfill was an
107
+ // estimate instead of silently relabelling it as exact.
108
+ estimated: result.total_cost_usd === lastValidResult.result.total_cost_usd &&
109
+ lastValidResult.result.total_cost_usd !== undefined
110
+ ? lastValidResult.estimated
111
+ : (lastValidResult.estimated || fallback.estimated),
112
+ authoritative: true,
113
+ };
114
+ }
115
+ return { ...fallback, authoritative: false };
116
+ }
117
+ const totals = {
118
+ tokens_in: 0,
119
+ tokens_out: 0,
120
+ tokens_cache_read: 0,
121
+ tokens_cache_create: 0,
122
+ total_cost_usd: 0,
123
+ num_turns: 0,
124
+ duration_ms: 0,
125
+ duration_api_ms: 0,
126
+ };
127
+ let model = fallbackModel ?? undefined;
128
+ let sessionId;
129
+ let baselineCost = 0;
130
+ let baselineTurns = 0;
131
+ let estimated = false;
132
+ let lastResultSeq = -1;
133
+ const resultRows = ports.events('results');
134
+ for (const row of resultRows) {
135
+ for (const event of parse(row)) {
136
+ if (event.kind !== 'result')
137
+ continue;
138
+ const finalised = ports.normalize(event, model);
139
+ const result = (0, usage_1.sanitizeRecoveredResult)(finalised.result);
140
+ totals.tokens_in += result.tokens_in ?? 0;
141
+ totals.tokens_out += result.tokens_out ?? 0;
142
+ totals.tokens_cache_read += result.tokens_cache_read ?? 0;
143
+ totals.tokens_cache_create += result.tokens_cache_create ?? 0;
144
+ const cumulativeCost = result.total_cost_usd ?? baselineCost;
145
+ totals.total_cost_usd += Math.max(0, cumulativeCost - baselineCost);
146
+ baselineCost = cumulativeCost;
147
+ const cumulativeTurns = result.num_turns ?? (baselineTurns + 1);
148
+ totals.num_turns += Math.max(0, cumulativeTurns - baselineTurns);
149
+ baselineTurns = cumulativeTurns;
150
+ totals.duration_ms += result.duration_ms ?? 0;
151
+ totals.duration_api_ms += result.duration_api_ms ?? 0;
152
+ model = result.model ?? model;
153
+ sessionId = result.session_id ?? sessionId;
154
+ estimated = estimated || finalised.estimated;
155
+ lastResultSeq = row.seq;
156
+ }
157
+ }
158
+ const tail = makeUsageAccumulator();
159
+ const tailRows = ports.events('tail', lastResultSeq);
160
+ for (const row of tailRows) {
161
+ for (const event of parse(row)) {
162
+ if (event.kind !== 'result')
163
+ tail.add(event, row.seq);
164
+ }
165
+ }
166
+ const tailUsage = tail.result();
167
+ const tailResult = tailUsage.result;
168
+ const hasTailUsage = [
169
+ tailResult.tokens_in,
170
+ tailResult.tokens_out,
171
+ tailResult.tokens_cache_read,
172
+ tailResult.tokens_cache_create,
173
+ tailResult.total_cost_usd,
174
+ ].some((value) => typeof value === 'number' && value > 0);
175
+ if (hasTailUsage) {
176
+ totals.tokens_in += tailResult.tokens_in ?? 0;
177
+ totals.tokens_out += tailResult.tokens_out ?? 0;
178
+ totals.tokens_cache_read += tailResult.tokens_cache_read ?? 0;
179
+ totals.tokens_cache_create += tailResult.tokens_cache_create ?? 0;
180
+ totals.total_cost_usd += tailResult.total_cost_usd ?? 0;
181
+ totals.num_turns += tailResult.num_turns ?? 1;
182
+ totals.duration_ms += tailResult.duration_ms ?? 0;
183
+ totals.duration_api_ms += tailResult.duration_api_ms ?? 0;
184
+ model = tailResult.model ?? model;
185
+ sessionId = tailResult.session_id ?? sessionId;
186
+ estimated = estimated || tailUsage.estimated;
187
+ }
188
+ const hasRecoveredUsage = Object.values(totals).some((value) => value > 0);
189
+ return {
190
+ result: hasRecoveredUsage
191
+ ? {
192
+ ...totals,
193
+ model,
194
+ session_id: sessionId,
195
+ }
196
+ : {},
197
+ estimated,
198
+ authoritative: false,
199
+ };
200
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.normalizePendingQueue = normalizePendingQueue;
4
+ exports.isDependencySatisfied = isDependencySatisfied;
5
+ /** Preserve the first occurrence; remove stale IDs without relaunching terminal jobs. */
6
+ function normalizePendingQueue(queue, jobs) {
7
+ const seen = new Set();
8
+ const normalizedQueue = [];
9
+ const removedJobIds = [];
10
+ for (const id of queue) {
11
+ if (seen.has(id))
12
+ continue;
13
+ seen.add(id);
14
+ if (jobs.get(id)?.status === 'queued')
15
+ normalizedQueue.push(id);
16
+ else
17
+ removedJobIds.push(id);
18
+ }
19
+ return { normalizedQueue, removedJobIds };
20
+ }
21
+ /** Historical/external missing dependencies are satisfied by the established contract. */
22
+ function isDependencySatisfied(parentStatus) {
23
+ return parentStatus === null || parentStatus === 'completed';
24
+ }
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sanitizeRecoveredResult = sanitizeRecoveredResult;
4
+ function sanitizeRecoveredResult(result) {
5
+ const safe = { ...result };
6
+ const numeric = [
7
+ 'tokens_in', 'tokens_out', 'tokens_cache_read', 'tokens_cache_create',
8
+ 'total_cost_usd', 'num_turns', 'duration_ms', 'duration_api_ms',
9
+ ];
10
+ for (const key of numeric) {
11
+ const value = safe[key];
12
+ if (value !== undefined && (typeof value !== 'number' || !Number.isFinite(value) || value < 0)) {
13
+ delete safe[key];
14
+ }
15
+ }
16
+ if (safe.model !== undefined && typeof safe.model !== 'string')
17
+ delete safe.model;
18
+ if (safe.session_id !== undefined && typeof safe.session_id !== 'string')
19
+ delete safe.session_id;
20
+ return safe;
21
+ }
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.enforceDailyBudgets = exports.sanitizeRecoveredResult = exports.recoverJobUsage = exports.recordJobInvocations = exports.isDependencySatisfied = exports.normalizePendingQueue = void 0;
4
+ var scheduling_1 = require("./domain/scheduling");
5
+ Object.defineProperty(exports, "normalizePendingQueue", { enumerable: true, get: function () { return scheduling_1.normalizePendingQueue; } });
6
+ Object.defineProperty(exports, "isDependencySatisfied", { enumerable: true, get: function () { return scheduling_1.isDependencySatisfied; } });
7
+ var record_job_invocations_1 = require("./application/record-job-invocations");
8
+ Object.defineProperty(exports, "recordJobInvocations", { enumerable: true, get: function () { return record_job_invocations_1.recordJobInvocations; } });
9
+ var recover_job_usage_1 = require("./application/recover-job-usage");
10
+ Object.defineProperty(exports, "recoverJobUsage", { enumerable: true, get: function () { return recover_job_usage_1.recoverJobUsage; } });
11
+ var usage_1 = require("./domain/usage");
12
+ Object.defineProperty(exports, "sanitizeRecoveredResult", { enumerable: true, get: function () { return usage_1.sanitizeRecoveredResult; } });
13
+ var enforce_budget_1 = require("./application/enforce-budget");
14
+ Object.defineProperty(exports, "enforceDailyBudgets", { enumerable: true, get: function () { return enforce_budget_1.enforceDailyBudgets; } });
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });