@nanobpm/nano-workforce 0.26.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 (115) hide show
  1. package/.github/workflows/ci.yml +60 -0
  2. package/.github/workflows/release.yml +58 -0
  3. package/.releaserc.json +17 -0
  4. package/AGENTS.md +168 -0
  5. package/CHANGELOG.md +231 -0
  6. package/LICENSE +202 -0
  7. package/README.md +303 -0
  8. package/SPEC.md +492 -0
  9. package/actions/abandon.test.ts +93 -0
  10. package/actions/abandon.ts +23 -0
  11. package/actions/blackboard.test.ts +195 -0
  12. package/actions/blackboard.ts +76 -0
  13. package/actions/cancel.ts +29 -0
  14. package/actions/feature-answer-hook.ts +44 -0
  15. package/actions/message.ts +49 -0
  16. package/actions/plan-hook.ts +19 -0
  17. package/actions/plan-start.ts +17 -0
  18. package/actions/start.ts +19 -0
  19. package/actions/status.ts +22 -0
  20. package/actions/webhook-submit.ts +21 -0
  21. package/app/abandon.test.ts +97 -0
  22. package/app/abandon.ts +105 -0
  23. package/app/baseGuard.test.ts +35 -0
  24. package/app/baseGuard.ts +62 -0
  25. package/app/blackboard.test.ts +295 -0
  26. package/app/blackboard.ts +301 -0
  27. package/app/github.test.ts +59 -0
  28. package/app/github.ts +647 -0
  29. package/app/mergeExclusion.test.ts +168 -0
  30. package/app/mergeExclusion.ts +211 -0
  31. package/app/mergeProtocol.test.ts +124 -0
  32. package/app/mergeProtocol.ts +193 -0
  33. package/app/mergeRebaseArm.test.ts +72 -0
  34. package/app/mergeTrain.test.ts +91 -0
  35. package/app/mergeTrain.ts +117 -0
  36. package/app/persist-escalation.test.ts +119 -0
  37. package/app/persist-round.test.ts +65 -0
  38. package/app/plan.test.ts +317 -0
  39. package/app/plan.ts +321 -0
  40. package/app/record-plan-review.test.ts +38 -0
  41. package/app/reviewWait.test.ts +70 -0
  42. package/app/reviewWait.ts +59 -0
  43. package/app/rounds.test.ts +74 -0
  44. package/app/rounds.ts +48 -0
  45. package/app/service.test.ts +101 -0
  46. package/app/service.ts +895 -0
  47. package/app/taskDelta.test.ts +144 -0
  48. package/app/taskDelta.ts +175 -0
  49. package/app/trialMerge.test.ts +15 -0
  50. package/app/trialMerge.ts +102 -0
  51. package/app/waves.test.ts +128 -0
  52. package/app/waves.ts +116 -0
  53. package/assets/icon.svg +13 -0
  54. package/components/review-round.json +69 -0
  55. package/db/migrations/001_init.sql +46 -0
  56. package/db/migrations/002_transcript.sql +7 -0
  57. package/db/migrations/003_open_escalation.sql +8 -0
  58. package/db/migrations/004_merge.sql +36 -0
  59. package/db/migrations/004_planning.sql +37 -0
  60. package/db/migrations/005_job_activation.sql +15 -0
  61. package/db/migrations/005_plan_deps.sql +20 -0
  62. package/db/migrations/006_plan_review.sql +22 -0
  63. package/db/migrations/006_task_escalation.sql +52 -0
  64. package/db/migrations/007_plan_review_job_key.sql +14 -0
  65. package/db/migrations/007_wave_gate.sql +16 -0
  66. package/db/migrations/008_review_nudge.sql +9 -0
  67. package/db/migrations/009_plan_blackboard.sql +46 -0
  68. package/db/migrations/010_plan_task_deltas.sql +27 -0
  69. package/db/migrations/011_plan_merge_exclusions.sql +26 -0
  70. package/db/migrations/012_merge_protocol_attempt.sql +4 -0
  71. package/db/migrations/013_merge_train_waiting_lane.sql +6 -0
  72. package/db/migrations/014_plan_trial_merges.sql +21 -0
  73. package/db/migrations/015_pr_abandon_token.sql +9 -0
  74. package/deno.json +24 -0
  75. package/deno.lock +1776 -0
  76. package/main.ts +71 -0
  77. package/nano-ide.ext.json +7 -0
  78. package/nano.app.json +138 -0
  79. package/nanobpm.project.json +20 -0
  80. package/package.json +56 -0
  81. package/pages/epic.page.json +195 -0
  82. package/pages/home.page.json +296 -0
  83. package/prompts/feature.md +132 -0
  84. package/prompts/fix-ci.md +65 -0
  85. package/prompts/plan-review.md +69 -0
  86. package/prompts/plan.md +183 -0
  87. package/prompts/rebase.md +82 -0
  88. package/prompts/review-round.md +171 -0
  89. package/prompts/trial-merge.md +43 -0
  90. package/renovate.json +21 -0
  91. package/resources/processes/convergence-loop.bpmn +399 -0
  92. package/resources/processes/merge-loop.bpmn +585 -0
  93. package/resources/processes/plan-fanout.bpmn +546 -0
  94. package/scripts/check-agent-prompts.test.ts +84 -0
  95. package/scripts/check-agent-prompts.ts +143 -0
  96. package/scripts/layout-bpmn.ts +99 -0
  97. package/scripts/purge-db.ts +57 -0
  98. package/scripts/upgrade-from-pack.ts +334 -0
  99. package/tsconfig.json +51 -0
  100. package/workers/arm-merge/worker.ts +18 -0
  101. package/workers/finalize/worker.ts +89 -0
  102. package/workers/mark-merged/worker.ts +21 -0
  103. package/workers/merge/worker.ts +119 -0
  104. package/workers/persist-escalation/worker.ts +107 -0
  105. package/workers/persist-round/worker.ts +52 -0
  106. package/workers/persist-task-escalation/worker.ts +112 -0
  107. package/workers/record-plan/worker.ts +135 -0
  108. package/workers/record-plan-review/worker.ts +92 -0
  109. package/workers/record-results/worker.ts +30 -0
  110. package/workers/record-trial-merge/worker.test.ts +104 -0
  111. package/workers/record-trial-merge/worker.ts +88 -0
  112. package/workers/record-wave/worker.test.ts +221 -0
  113. package/workers/record-wave/worker.ts +308 -0
  114. package/workers/select-wave/worker.test.ts +130 -0
  115. package/workers/select-wave/worker.ts +84 -0
@@ -0,0 +1,585 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:zeebe="http://camunda.org/schema/zeebe/1.0" xmlns:nano="https://nanobpm.io/schema/shapes/1.0" id="Definitions_nano_workforce_merge" targetNamespace="http://nanobpm.io/nano-workforce">
3
+ <bpmn:message id="Message_depsCleared" name="deps-cleared">
4
+ <bpmn:extensionElements>
5
+ <zeebe:subscription correlationKey="=prKey" />
6
+ </bpmn:extensionElements>
7
+ </bpmn:message>
8
+ <bpmn:message id="Message_mergeReady" name="merge-ready">
9
+ <bpmn:extensionElements>
10
+ <zeebe:subscription correlationKey="=prKey" />
11
+ <zeebe:properties>
12
+ <zeebe:property name="io.nanobpm.dataEnvelope.in" value="MergeReady" />
13
+ </zeebe:properties>
14
+ </bpmn:extensionElements>
15
+ </bpmn:message>
16
+ <bpmn:message id="Message_mergeLanded" name="merge-landed">
17
+ <bpmn:extensionElements>
18
+ <zeebe:subscription correlationKey="=prKey" />
19
+ </bpmn:extensionElements>
20
+ </bpmn:message>
21
+ <bpmn:message id="Message_mergeEscAnswered" name="escalation-answered">
22
+ <bpmn:extensionElements>
23
+ <zeebe:subscription correlationKey="=prKey" />
24
+ <zeebe:properties>
25
+ <zeebe:property name="io.nanobpm.dataEnvelope.in" value="MergeEscalationAnswered" />
26
+ </zeebe:properties>
27
+ </bpmn:extensionElements>
28
+ </bpmn:message>
29
+ <bpmn:process id="merge-loop" name="PR Merge" isExecutable="true">
30
+ <bpmn:extensionElements>
31
+ <nano:shapes>
32
+ <nano:shape id="MergeArmIn" name="Arm merge poller — input">
33
+ <nano:extend name="prKey" type="string" />
34
+ </nano:shape>
35
+ <nano:shape id="MergeAttemptIn" name="Attempt merge — input">
36
+ <nano:extend name="prKey" type="string" />
37
+ <nano:extend name="repo" type="string" />
38
+ <nano:extend name="prNumber" type="integer" />
39
+ </nano:shape>
40
+ <nano:shape id="MergeAttemptOut" name="Attempt merge — result">
41
+ <nano:extend name="mergeStatus" type="string" />
42
+ <nano:extend name="status" type="string" optional="true" />
43
+ <nano:extend name="question" type="string" optional="true" />
44
+ </nano:shape>
45
+ <nano:shape id="MergeEscalationIn" name="Record merge escalation — input">
46
+ <nano:extend name="prKey" type="string" />
47
+ <nano:extend name="round" type="integer" />
48
+ <nano:extend name="status" type="string" optional="true" />
49
+ <nano:extend name="summary" type="string" optional="true" />
50
+ <nano:extend name="question" type="string" optional="true" />
51
+ </nano:shape>
52
+ <nano:shape id="MergeEscalationOut" name="Record merge escalation — result">
53
+ <nano:extend name="escalationId" type="integer" />
54
+ </nano:shape>
55
+ <nano:shape id="MarkMergedIn" name="Mark merged — input">
56
+ <nano:extend name="prKey" type="string" />
57
+ </nano:shape>
58
+ <nano:shape id="MergeReady" name="merge-ready message payload">
59
+ <nano:extend name="mergeState" type="string" />
60
+ <nano:extend name="failingChecks" type="integer" optional="true" />
61
+ <nano:extend name="failingChecksList" type="string" optional="true" />
62
+ </nano:shape>
63
+ <nano:shape id="FixCiIn" name="CI fix — input">
64
+ <nano:extend name="prKey" type="string" />
65
+ <nano:extend name="repo" type="string" />
66
+ <nano:extend name="prNumber" type="integer" />
67
+ <nano:extend name="prUrl" type="string" />
68
+ <nano:extend name="ciFixRound" type="integer" />
69
+ </nano:shape>
70
+ <nano:shape id="FixCiOut" name="CI fix — result">
71
+ <nano:extend name="status" type="string" />
72
+ <nano:extend name="summary" type="string" optional="true" />
73
+ <nano:extend name="question" type="string" optional="true" />
74
+ </nano:shape>
75
+ <nano:shape id="RebaseIn" name="Rebase — input">
76
+ <nano:extend name="prKey" type="string" />
77
+ <nano:extend name="repo" type="string" />
78
+ <nano:extend name="prNumber" type="integer" />
79
+ <nano:extend name="prUrl" type="string" />
80
+ <nano:extend name="rebaseRound" type="integer" />
81
+ </nano:shape>
82
+ <nano:shape id="RebaseOut" name="Rebase — result">
83
+ <nano:extend name="status" type="string" />
84
+ <nano:extend name="summary" type="string" optional="true" />
85
+ <nano:extend name="question" type="string" optional="true" />
86
+ </nano:shape>
87
+ <nano:shape id="MergeEscalationAnswered" name="escalation-answered message payload">
88
+ <nano:extend name="answer" type="string" />
89
+ <nano:extend name="escalationId" type="integer" />
90
+ </nano:shape>
91
+ </nano:shapes>
92
+ </bpmn:extensionElements>
93
+ <bpmn:startEvent id="MergeStart" name="PR converged">
94
+ <bpmn:outgoing>f_m_start</bpmn:outgoing>
95
+ </bpmn:startEvent>
96
+ <bpmn:intermediateCatchEvent id="wait-deps" name="Wait: dependencies merged">
97
+ <bpmn:incoming>f_m_start</bpmn:incoming>
98
+ <bpmn:outgoing>f_m_deps</bpmn:outgoing>
99
+ <bpmn:messageEventDefinition id="med_depsCleared" messageRef="Message_depsCleared" />
100
+ </bpmn:intermediateCatchEvent>
101
+ <bpmn:serviceTask id="arm-merge" name="Arm merge poller">
102
+ <bpmn:extensionElements>
103
+ <zeebe:taskDefinition type="pr.arm-merge" />
104
+ <zeebe:properties>
105
+ <zeebe:property name="io.nanobpm.dataEnvelope.in" value="MergeArmIn" />
106
+ </zeebe:properties>
107
+ </bpmn:extensionElements>
108
+ <bpmn:incoming>f_m_deps</bpmn:incoming>
109
+ <bpmn:incoming>f_m_answer</bpmn:incoming>
110
+ <bpmn:incoming>f_ci_fixed</bpmn:incoming>
111
+ <bpmn:incoming>f_reb_rebased</bpmn:incoming>
112
+ <bpmn:outgoing>f_m_arm</bpmn:outgoing>
113
+ </bpmn:serviceTask>
114
+ <bpmn:intermediateCatchEvent id="wait-mergeable" name="Wait: mergeable">
115
+ <bpmn:incoming>f_m_arm</bpmn:incoming>
116
+ <bpmn:outgoing>f_m_ready</bpmn:outgoing>
117
+ <bpmn:messageEventDefinition id="med_mergeReady" messageRef="Message_mergeReady" />
118
+ </bpmn:intermediateCatchEvent>
119
+ <bpmn:exclusiveGateway id="gw-mergeable" name="mergeable?" default="f_m_mBlocked">
120
+ <bpmn:incoming>f_m_ready</bpmn:incoming>
121
+ <bpmn:outgoing>f_m_mReady</bpmn:outgoing>
122
+ <bpmn:outgoing>f_m_mCiFix</bpmn:outgoing>
123
+ <bpmn:outgoing>f_m_mRebase</bpmn:outgoing>
124
+ <bpmn:outgoing>f_m_mBlocked</bpmn:outgoing>
125
+ </bpmn:exclusiveGateway>
126
+ <bpmn:serviceTask id="attempt-merge" name="Merge PR">
127
+ <bpmn:extensionElements>
128
+ <zeebe:taskDefinition type="pr.merge" />
129
+ <zeebe:properties>
130
+ <zeebe:property name="io.nanobpm.dataEnvelope.in" value="MergeAttemptIn" />
131
+ <zeebe:property name="io.nanobpm.dataEnvelope.out" value="MergeAttemptOut" />
132
+ </zeebe:properties>
133
+ </bpmn:extensionElements>
134
+ <bpmn:incoming>f_m_mReady</bpmn:incoming>
135
+ <bpmn:outgoing>f_m_attempt</bpmn:outgoing>
136
+ </bpmn:serviceTask>
137
+ <bpmn:exclusiveGateway id="gw-merge" name="merge result?" default="f_m_gBlocked">
138
+ <bpmn:incoming>f_m_attempt</bpmn:incoming>
139
+ <bpmn:outgoing>f_m_gMerged</bpmn:outgoing>
140
+ <bpmn:outgoing>f_m_gQueued</bpmn:outgoing>
141
+ <bpmn:outgoing>f_m_gBlocked</bpmn:outgoing>
142
+ </bpmn:exclusiveGateway>
143
+ <bpmn:intermediateCatchEvent id="wait-landed" name="Wait: merge queue landed">
144
+ <bpmn:incoming>f_m_gQueued</bpmn:incoming>
145
+ <bpmn:outgoing>f_m_landed</bpmn:outgoing>
146
+ <bpmn:messageEventDefinition id="med_mergeLanded" messageRef="Message_mergeLanded" />
147
+ </bpmn:intermediateCatchEvent>
148
+ <bpmn:serviceTask id="mark-merged" name="Mark merged">
149
+ <bpmn:extensionElements>
150
+ <zeebe:taskDefinition type="pr.mark-merged" />
151
+ <zeebe:properties>
152
+ <zeebe:property name="io.nanobpm.dataEnvelope.in" value="MarkMergedIn" />
153
+ </zeebe:properties>
154
+ </bpmn:extensionElements>
155
+ <bpmn:incoming>f_m_gMerged</bpmn:incoming>
156
+ <bpmn:incoming>f_m_landed</bpmn:incoming>
157
+ <bpmn:outgoing>f_m_done</bpmn:outgoing>
158
+ </bpmn:serviceTask>
159
+ <bpmn:endEvent id="MergeEnd" name="Merged">
160
+ <bpmn:incoming>f_m_done</bpmn:incoming>
161
+ </bpmn:endEvent>
162
+ <bpmn:serviceTask id="merge-esc-conflict" name="Escalate: not mergeable">
163
+ <bpmn:extensionElements>
164
+ <zeebe:taskDefinition type="pr.persist-escalation" />
165
+ <zeebe:properties>
166
+ <zeebe:property name="io.nanobpm.dataEnvelope.in" value="MergeEscalationIn" />
167
+ <zeebe:property name="io.nanobpm.dataEnvelope.out" value="MergeEscalationOut" />
168
+ </zeebe:properties>
169
+ <zeebe:ioMapping>
170
+ <zeebe:input source="=&#34;blocked&#34;" target="status" />
171
+ <zeebe:input source="=&#34;This PR is not mergeable (state: &#34; + mergeState + &#34;). Resolve the conflict or failing required check on the branch, then reply to retry.&#34;" target="question" />
172
+ </zeebe:ioMapping>
173
+ </bpmn:extensionElements>
174
+ <bpmn:incoming>f_m_mBlocked</bpmn:incoming>
175
+ <bpmn:incoming>f_ci_giveup</bpmn:incoming>
176
+ <bpmn:incoming>f_reb_giveup</bpmn:incoming>
177
+ <bpmn:outgoing>f_m_escC</bpmn:outgoing>
178
+ </bpmn:serviceTask>
179
+ <bpmn:serviceTask id="merge-esc-attempt" name="Escalate: merge blocked">
180
+ <bpmn:extensionElements>
181
+ <zeebe:taskDefinition type="pr.persist-escalation" />
182
+ <zeebe:properties>
183
+ <zeebe:property name="io.nanobpm.dataEnvelope.in" value="MergeEscalationIn" />
184
+ <zeebe:property name="io.nanobpm.dataEnvelope.out" value="MergeEscalationOut" />
185
+ </zeebe:properties>
186
+ </bpmn:extensionElements>
187
+ <bpmn:incoming>f_m_gBlocked</bpmn:incoming>
188
+ <bpmn:incoming>f_ci_blocked</bpmn:incoming>
189
+ <bpmn:incoming>f_reb_blocked</bpmn:incoming>
190
+ <bpmn:outgoing>f_m_escA</bpmn:outgoing>
191
+ </bpmn:serviceTask>
192
+ <bpmn:intermediateCatchEvent id="wait-merge-answer" name="Wait: escalation answered">
193
+ <bpmn:incoming>f_m_escC</bpmn:incoming>
194
+ <bpmn:incoming>f_m_escA</bpmn:incoming>
195
+ <bpmn:outgoing>f_m_answer</bpmn:outgoing>
196
+ <bpmn:messageEventDefinition id="med_mergeEscAnswered" messageRef="Message_mergeEscAnswered" />
197
+ </bpmn:intermediateCatchEvent>
198
+ <bpmn:exclusiveGateway id="gw-ci-fix" name="auto-fix CI?" default="f_ci_giveup">
199
+ <bpmn:incoming>f_m_mCiFix</bpmn:incoming>
200
+ <bpmn:outgoing>f_ci_go</bpmn:outgoing>
201
+ <bpmn:outgoing>f_ci_giveup</bpmn:outgoing>
202
+ </bpmn:exclusiveGateway>
203
+ <bpmn:serviceTask id="fix-ci" name="Fix CI (agent)">
204
+ <bpmn:extensionElements>
205
+ <zeebe:taskDefinition type="senior:fix-ci" />
206
+ <zeebe:taskHeaders>
207
+ <zeebe:header key="io.nanobpm.agentTask.task.prompt" value="{{fix-ci}}" />
208
+ </zeebe:taskHeaders>
209
+ <zeebe:properties>
210
+ <zeebe:property name="io.nanobpm.dataEnvelope.in" value="FixCiIn" />
211
+ <zeebe:property name="io.nanobpm.dataEnvelope.out" value="FixCiOut" />
212
+ </zeebe:properties>
213
+ <zeebe:ioMapping>
214
+ <zeebe:input source="=(if (failingChecksList = null or failingChecksList = &#34;&#34;) then &#34;&#34; else &#34;&#10;&#10;Failing checks to make green:&#10;&#34; + failingChecksList) + (if (abandonBrief = null) then &#34;&#34; else abandonBrief)" target="appendPrompt" />
215
+ <zeebe:output source="=ciFixRound + 1" target="ciFixRound" />
216
+ </zeebe:ioMapping>
217
+ </bpmn:extensionElements>
218
+ <bpmn:incoming>f_ci_go</bpmn:incoming>
219
+ <bpmn:outgoing>f_ci_done</bpmn:outgoing>
220
+ </bpmn:serviceTask>
221
+ <bpmn:exclusiveGateway id="gw-ci-result" name="fixed?" default="f_ci_blocked">
222
+ <bpmn:incoming>f_ci_done</bpmn:incoming>
223
+ <bpmn:outgoing>f_ci_fixed</bpmn:outgoing>
224
+ <bpmn:outgoing>f_ci_blocked</bpmn:outgoing>
225
+ </bpmn:exclusiveGateway>
226
+ <bpmn:exclusiveGateway id="gw-rebase" name="auto-rebase?" default="f_reb_giveup">
227
+ <bpmn:incoming>f_m_mRebase</bpmn:incoming>
228
+ <bpmn:outgoing>f_reb_go</bpmn:outgoing>
229
+ <bpmn:outgoing>f_reb_giveup</bpmn:outgoing>
230
+ </bpmn:exclusiveGateway>
231
+ <bpmn:serviceTask id="rebase" name="Rebase (agent)">
232
+ <bpmn:extensionElements>
233
+ <zeebe:taskDefinition type="senior:rebase" />
234
+ <zeebe:taskHeaders>
235
+ <zeebe:header key="io.nanobpm.agentTask.task.prompt" value="{{rebase}}" />
236
+ </zeebe:taskHeaders>
237
+ <zeebe:properties>
238
+ <zeebe:property name="io.nanobpm.dataEnvelope.in" value="RebaseIn" />
239
+ <zeebe:property name="io.nanobpm.dataEnvelope.out" value="RebaseOut" />
240
+ </zeebe:properties>
241
+ <zeebe:ioMapping>
242
+ <zeebe:input source="=(if (abandonBrief = null) then &#34;&#34; else abandonBrief)" target="appendPrompt" />
243
+ <zeebe:output source="=rebaseRound + 1" target="rebaseRound" />
244
+ </zeebe:ioMapping>
245
+ </bpmn:extensionElements>
246
+ <bpmn:incoming>f_reb_go</bpmn:incoming>
247
+ <bpmn:outgoing>f_reb_done</bpmn:outgoing>
248
+ </bpmn:serviceTask>
249
+ <bpmn:exclusiveGateway id="gw-rebase-result" name="rebased?" default="f_reb_blocked">
250
+ <bpmn:incoming>f_reb_done</bpmn:incoming>
251
+ <bpmn:outgoing>f_reb_rebased</bpmn:outgoing>
252
+ <bpmn:outgoing>f_reb_blocked</bpmn:outgoing>
253
+ </bpmn:exclusiveGateway>
254
+ <bpmn:sequenceFlow id="f_m_start" sourceRef="MergeStart" targetRef="wait-deps" />
255
+ <bpmn:sequenceFlow id="f_m_deps" sourceRef="wait-deps" targetRef="arm-merge" />
256
+ <bpmn:sequenceFlow id="f_m_arm" sourceRef="arm-merge" targetRef="wait-mergeable" />
257
+ <bpmn:sequenceFlow id="f_m_ready" sourceRef="wait-mergeable" targetRef="gw-mergeable" />
258
+ <bpmn:sequenceFlow id="f_m_mReady" name="ready" sourceRef="gw-mergeable" targetRef="attempt-merge">
259
+ <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">=mergeState = "ready"</bpmn:conditionExpression>
260
+ </bpmn:sequenceFlow>
261
+ <bpmn:sequenceFlow id="f_m_mCiFix" name="blocked (failing checks)" sourceRef="gw-mergeable" targetRef="gw-ci-fix">
262
+ <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">=mergeState = "blocked"</bpmn:conditionExpression>
263
+ </bpmn:sequenceFlow>
264
+ <bpmn:sequenceFlow id="f_m_mRebase" name="conflict" sourceRef="gw-mergeable" targetRef="gw-rebase">
265
+ <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">=mergeState = "conflict"</bpmn:conditionExpression>
266
+ </bpmn:sequenceFlow>
267
+ <bpmn:sequenceFlow id="f_m_mBlocked" name="not landable" sourceRef="gw-mergeable" targetRef="merge-esc-conflict" />
268
+ <bpmn:sequenceFlow id="f_ci_go" name="within budget" sourceRef="gw-ci-fix" targetRef="fix-ci">
269
+ <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">=ciFixRound &lt; ciFixMax and failingChecks &gt; 0</bpmn:conditionExpression>
270
+ </bpmn:sequenceFlow>
271
+ <bpmn:sequenceFlow id="f_ci_giveup" name="budget exhausted" sourceRef="gw-ci-fix" targetRef="merge-esc-conflict" />
272
+ <bpmn:sequenceFlow id="f_ci_done" sourceRef="fix-ci" targetRef="gw-ci-result" />
273
+ <bpmn:sequenceFlow id="f_ci_fixed" name="fixed" sourceRef="gw-ci-result" targetRef="arm-merge">
274
+ <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">=status = "fixed"</bpmn:conditionExpression>
275
+ </bpmn:sequenceFlow>
276
+ <bpmn:sequenceFlow id="f_ci_blocked" name="could not fix" sourceRef="gw-ci-result" targetRef="merge-esc-attempt" />
277
+ <bpmn:sequenceFlow id="f_reb_go" name="within budget" sourceRef="gw-rebase" targetRef="rebase">
278
+ <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">=rebaseRound &lt; rebaseMax</bpmn:conditionExpression>
279
+ </bpmn:sequenceFlow>
280
+ <bpmn:sequenceFlow id="f_reb_giveup" name="budget exhausted" sourceRef="gw-rebase" targetRef="merge-esc-conflict" />
281
+ <bpmn:sequenceFlow id="f_reb_done" sourceRef="rebase" targetRef="gw-rebase-result" />
282
+ <bpmn:sequenceFlow id="f_reb_rebased" name="rebased" sourceRef="gw-rebase-result" targetRef="arm-merge">
283
+ <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">=status = "rebased"</bpmn:conditionExpression>
284
+ </bpmn:sequenceFlow>
285
+ <bpmn:sequenceFlow id="f_reb_blocked" name="could not resolve" sourceRef="gw-rebase-result" targetRef="merge-esc-attempt" />
286
+ <bpmn:sequenceFlow id="f_m_attempt" sourceRef="attempt-merge" targetRef="gw-merge" />
287
+ <bpmn:sequenceFlow id="f_m_gMerged" name="merged" sourceRef="gw-merge" targetRef="mark-merged">
288
+ <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">=mergeStatus = "merged"</bpmn:conditionExpression>
289
+ </bpmn:sequenceFlow>
290
+ <bpmn:sequenceFlow id="f_m_gQueued" name="queued" sourceRef="gw-merge" targetRef="wait-landed">
291
+ <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">=mergeStatus = "queued"</bpmn:conditionExpression>
292
+ </bpmn:sequenceFlow>
293
+ <bpmn:sequenceFlow id="f_m_gBlocked" name="blocked" sourceRef="gw-merge" targetRef="merge-esc-attempt" />
294
+ <bpmn:sequenceFlow id="f_m_landed" sourceRef="wait-landed" targetRef="mark-merged" />
295
+ <bpmn:sequenceFlow id="f_m_done" sourceRef="mark-merged" targetRef="MergeEnd" />
296
+ <bpmn:sequenceFlow id="f_m_escC" sourceRef="merge-esc-conflict" targetRef="wait-merge-answer" />
297
+ <bpmn:sequenceFlow id="f_m_escA" sourceRef="merge-esc-attempt" targetRef="wait-merge-answer" />
298
+ <bpmn:sequenceFlow id="f_m_answer" sourceRef="wait-merge-answer" targetRef="arm-merge" />
299
+ </bpmn:process>
300
+ <bpmndi:BPMNDiagram id="BPMNDiagram_merge-loop">
301
+ <bpmndi:BPMNPlane id="BPMNPlane_merge-loop" bpmnElement="merge-loop">
302
+ <bpmndi:BPMNShape id="BPMNShape_MergeStart" bpmnElement="MergeStart">
303
+ <dc:Bounds x="80" y="102" width="36" height="36" />
304
+ <bpmndi:BPMNLabel>
305
+ <dc:Bounds x="54" y="143" width="89" height="14" />
306
+ </bpmndi:BPMNLabel>
307
+ </bpmndi:BPMNShape>
308
+ <bpmndi:BPMNShape id="BPMNShape_wait-deps" bpmnElement="wait-deps">
309
+ <dc:Bounds x="216" y="102" width="36" height="36" />
310
+ <bpmndi:BPMNLabel>
311
+ <dc:Bounds x="190" y="143" width="88" height="42" />
312
+ </bpmndi:BPMNLabel>
313
+ </bpmndi:BPMNShape>
314
+ <bpmndi:BPMNShape id="BPMNShape_arm-merge" bpmnElement="arm-merge">
315
+ <dc:Bounds x="352" y="80" width="100" height="80" />
316
+ </bpmndi:BPMNShape>
317
+ <bpmndi:BPMNShape id="BPMNShape_wait-mergeable" bpmnElement="wait-mergeable">
318
+ <dc:Bounds x="552" y="102" width="36" height="36" />
319
+ <bpmndi:BPMNLabel>
320
+ <dc:Bounds x="535" y="143" width="70" height="28" />
321
+ </bpmndi:BPMNLabel>
322
+ </bpmndi:BPMNShape>
323
+ <bpmndi:BPMNShape id="BPMNShape_gw-mergeable" bpmnElement="gw-mergeable" isMarkerVisible="true">
324
+ <dc:Bounds x="688" y="95" width="50" height="50" />
325
+ <bpmndi:BPMNLabel>
326
+ <dc:Bounds x="675" y="76" width="77" height="14" />
327
+ </bpmndi:BPMNLabel>
328
+ </bpmndi:BPMNShape>
329
+ <bpmndi:BPMNShape id="BPMNShape_attempt-merge" bpmnElement="attempt-merge">
330
+ <dc:Bounds x="838" y="80" width="100" height="80" />
331
+ </bpmndi:BPMNShape>
332
+ <bpmndi:BPMNShape id="BPMNShape_gw-merge" bpmnElement="gw-merge" isMarkerVisible="true">
333
+ <dc:Bounds x="1063" y="95" width="50" height="50" />
334
+ <bpmndi:BPMNLabel>
335
+ <dc:Bounds x="1062" y="62" width="53" height="28" />
336
+ </bpmndi:BPMNLabel>
337
+ </bpmndi:BPMNShape>
338
+ <bpmndi:BPMNShape id="BPMNShape_wait-landed" bpmnElement="wait-landed">
339
+ <dc:Bounds x="1245" y="262" width="36" height="36" />
340
+ <bpmndi:BPMNLabel>
341
+ <dc:Bounds x="1221" y="229" width="85" height="28" />
342
+ </bpmndi:BPMNLabel>
343
+ </bpmndi:BPMNShape>
344
+ <bpmndi:BPMNShape id="BPMNShape_mark-merged" bpmnElement="mark-merged">
345
+ <dc:Bounds x="1388" y="80" width="100" height="80" />
346
+ </bpmndi:BPMNShape>
347
+ <bpmndi:BPMNShape id="BPMNShape_MergeEnd" bpmnElement="MergeEnd">
348
+ <dc:Bounds x="1588" y="102" width="36" height="36" />
349
+ <bpmndi:BPMNLabel>
350
+ <dc:Bounds x="1581" y="143" width="50" height="14" />
351
+ </bpmndi:BPMNLabel>
352
+ </bpmndi:BPMNShape>
353
+ <bpmndi:BPMNShape id="BPMNShape_merge-esc-conflict" bpmnElement="merge-esc-conflict">
354
+ <dc:Bounds x="1038" y="560" width="100" height="80" />
355
+ </bpmndi:BPMNShape>
356
+ <bpmndi:BPMNShape id="BPMNShape_merge-esc-attempt" bpmnElement="merge-esc-attempt">
357
+ <dc:Bounds x="1388" y="400" width="100" height="80" />
358
+ </bpmndi:BPMNShape>
359
+ <bpmndi:BPMNShape id="BPMNShape_wait-merge-answer" bpmnElement="wait-merge-answer">
360
+ <dc:Bounds x="1588" y="422" width="36" height="36" />
361
+ <bpmndi:BPMNLabel>
362
+ <dc:Bounds x="1649" y="463" width="74" height="42" />
363
+ </bpmndi:BPMNLabel>
364
+ </bpmndi:BPMNShape>
365
+ <bpmndi:BPMNShape id="BPMNShape_gw-ci-fix" bpmnElement="gw-ci-fix" isMarkerVisible="true">
366
+ <dc:Bounds x="863" y="575" width="50" height="50" />
367
+ <bpmndi:BPMNLabel>
368
+ <dc:Bounds x="844" y="556" width="89" height="14" />
369
+ </bpmndi:BPMNLabel>
370
+ </bpmndi:BPMNShape>
371
+ <bpmndi:BPMNShape id="BPMNShape_fix-ci" bpmnElement="fix-ci">
372
+ <dc:Bounds x="1038" y="720" width="100" height="80" />
373
+ </bpmndi:BPMNShape>
374
+ <bpmndi:BPMNShape id="BPMNShape_gw-ci-result" bpmnElement="gw-ci-result" isMarkerVisible="true">
375
+ <dc:Bounds x="1238" y="735" width="50" height="50" />
376
+ <bpmndi:BPMNLabel>
377
+ <dc:Bounds x="1240" y="716" width="46" height="14" />
378
+ </bpmndi:BPMNLabel>
379
+ </bpmndi:BPMNShape>
380
+ <bpmndi:BPMNShape id="BPMNShape_gw-rebase" bpmnElement="gw-rebase" isMarkerVisible="true">
381
+ <dc:Bounds x="863" y="255" width="50" height="50" />
382
+ <bpmndi:BPMNLabel>
383
+ <dc:Bounds x="844" y="236" width="88" height="14" />
384
+ </bpmndi:BPMNLabel>
385
+ </bpmndi:BPMNShape>
386
+ <bpmndi:BPMNShape id="BPMNShape_rebase" bpmnElement="rebase">
387
+ <dc:Bounds x="1038" y="880" width="100" height="80" />
388
+ </bpmndi:BPMNShape>
389
+ <bpmndi:BPMNShape id="BPMNShape_gw-rebase-result" bpmnElement="gw-rebase-result" isMarkerVisible="true">
390
+ <dc:Bounds x="1238" y="895" width="50" height="50" />
391
+ <bpmndi:BPMNLabel>
392
+ <dc:Bounds x="1233" y="876" width="60" height="14" />
393
+ </bpmndi:BPMNLabel>
394
+ </bpmndi:BPMNShape>
395
+ <bpmndi:BPMNEdge id="BPMNEdge_f_m_start" bpmnElement="f_m_start">
396
+ <di:waypoint x="116" y="120" />
397
+ <di:waypoint x="216" y="120" />
398
+ </bpmndi:BPMNEdge>
399
+ <bpmndi:BPMNEdge id="BPMNEdge_f_m_deps" bpmnElement="f_m_deps">
400
+ <di:waypoint x="252" y="120" />
401
+ <di:waypoint x="352" y="120" />
402
+ </bpmndi:BPMNEdge>
403
+ <bpmndi:BPMNEdge id="BPMNEdge_f_m_arm" bpmnElement="f_m_arm">
404
+ <di:waypoint x="452" y="120" />
405
+ <di:waypoint x="552" y="120" />
406
+ </bpmndi:BPMNEdge>
407
+ <bpmndi:BPMNEdge id="BPMNEdge_f_m_ready" bpmnElement="f_m_ready">
408
+ <di:waypoint x="588" y="120" />
409
+ <di:waypoint x="688" y="120" />
410
+ </bpmndi:BPMNEdge>
411
+ <bpmndi:BPMNEdge id="BPMNEdge_f_m_mReady" bpmnElement="f_m_mReady">
412
+ <di:waypoint x="738" y="120" />
413
+ <di:waypoint x="838" y="120" />
414
+ <bpmndi:BPMNLabel>
415
+ <dc:Bounds x="769" y="98" width="39" height="14" />
416
+ </bpmndi:BPMNLabel>
417
+ </bpmndi:BPMNEdge>
418
+ <bpmndi:BPMNEdge id="BPMNEdge_f_m_attempt" bpmnElement="f_m_attempt">
419
+ <di:waypoint x="938" y="120" />
420
+ <di:waypoint x="1063" y="120" />
421
+ </bpmndi:BPMNEdge>
422
+ <bpmndi:BPMNEdge id="BPMNEdge_f_m_gMerged" bpmnElement="f_m_gMerged">
423
+ <di:waypoint x="1113" y="120" />
424
+ <di:waypoint x="1388" y="120" />
425
+ <bpmndi:BPMNLabel>
426
+ <dc:Bounds x="1216" y="98" width="49" height="14" />
427
+ </bpmndi:BPMNLabel>
428
+ </bpmndi:BPMNEdge>
429
+ <bpmndi:BPMNEdge id="BPMNEdge_f_m_done" bpmnElement="f_m_done">
430
+ <di:waypoint x="1488" y="120" />
431
+ <di:waypoint x="1588" y="120" />
432
+ </bpmndi:BPMNEdge>
433
+ <bpmndi:BPMNEdge id="BPMNEdge_f_ci_giveup" bpmnElement="f_ci_giveup">
434
+ <di:waypoint x="913" y="600" />
435
+ <di:waypoint x="1038" y="600" />
436
+ <bpmndi:BPMNLabel>
437
+ <dc:Bounds x="942" y="605" width="67" height="28" />
438
+ </bpmndi:BPMNLabel>
439
+ </bpmndi:BPMNEdge>
440
+ <bpmndi:BPMNEdge id="BPMNEdge_f_ci_blocked" bpmnElement="f_ci_blocked">
441
+ <di:waypoint x="1288" y="760" />
442
+ <di:waypoint x="1438" y="760" />
443
+ <di:waypoint x="1438" y="480" />
444
+ <bpmndi:BPMNLabel>
445
+ <dc:Bounds x="1319" y="738" width="89" height="14" />
446
+ </bpmndi:BPMNLabel>
447
+ </bpmndi:BPMNEdge>
448
+ <bpmndi:BPMNEdge id="BPMNEdge_f_reb_giveup" bpmnElement="f_reb_giveup">
449
+ <di:waypoint x="913" y="280" />
450
+ <di:waypoint x="1088" y="280" />
451
+ <di:waypoint x="1088" y="560" />
452
+ <bpmndi:BPMNLabel>
453
+ <dc:Bounds x="977" y="247" width="67" height="28" />
454
+ </bpmndi:BPMNLabel>
455
+ </bpmndi:BPMNEdge>
456
+ <bpmndi:BPMNEdge id="BPMNEdge_f_reb_blocked" bpmnElement="f_reb_blocked">
457
+ <di:waypoint x="1288" y="920" />
458
+ <di:waypoint x="1438" y="920" />
459
+ <di:waypoint x="1438" y="480" />
460
+ <bpmndi:BPMNLabel>
461
+ <dc:Bounds x="1331" y="887" width="64" height="28" />
462
+ </bpmndi:BPMNLabel>
463
+ </bpmndi:BPMNEdge>
464
+ <bpmndi:BPMNEdge id="BPMNEdge_f_m_escC" bpmnElement="f_m_escC">
465
+ <di:waypoint x="1138" y="580" />
466
+ <di:waypoint x="1158" y="580" />
467
+ <di:waypoint x="1158" y="380" />
468
+ <di:waypoint x="1606" y="380" />
469
+ <di:waypoint x="1606" y="422" />
470
+ </bpmndi:BPMNEdge>
471
+ <bpmndi:BPMNEdge id="BPMNEdge_f_m_escA" bpmnElement="f_m_escA">
472
+ <di:waypoint x="1488" y="440" />
473
+ <di:waypoint x="1588" y="440" />
474
+ </bpmndi:BPMNEdge>
475
+ <bpmndi:BPMNEdge id="BPMNEdge_f_m_answer" bpmnElement="f_m_answer">
476
+ <di:waypoint x="1606" y="458" />
477
+ <di:waypoint x="1606" y="500" />
478
+ <di:waypoint x="402" y="500" />
479
+ <di:waypoint x="402" y="160" />
480
+ </bpmndi:BPMNEdge>
481
+ <bpmndi:BPMNEdge id="BPMNEdge_f_m_mCiFix" bpmnElement="f_m_mCiFix">
482
+ <di:waypoint x="713" y="145" />
483
+ <di:waypoint x="713" y="600" />
484
+ <di:waypoint x="863" y="600" />
485
+ <bpmndi:BPMNLabel>
486
+ <dc:Bounds x="718" y="438" width="60" height="42" />
487
+ </bpmndi:BPMNLabel>
488
+ </bpmndi:BPMNEdge>
489
+ <bpmndi:BPMNEdge id="BPMNEdge_f_m_mRebase" bpmnElement="f_m_mRebase">
490
+ <di:waypoint x="713" y="145" />
491
+ <di:waypoint x="713" y="280" />
492
+ <di:waypoint x="863" y="280" />
493
+ <bpmndi:BPMNLabel>
494
+ <dc:Bounds x="758" y="258" width="60" height="14" />
495
+ </bpmndi:BPMNLabel>
496
+ </bpmndi:BPMNEdge>
497
+ <bpmndi:BPMNEdge id="BPMNEdge_f_m_mBlocked" bpmnElement="f_m_mBlocked">
498
+ <di:waypoint x="713" y="145" />
499
+ <di:waypoint x="713" y="318" />
500
+ <di:waypoint x="1018" y="318" />
501
+ <di:waypoint x="1018" y="580" />
502
+ <di:waypoint x="1038" y="580" />
503
+ <bpmndi:BPMNLabel>
504
+ <dc:Bounds x="823" y="326" width="85" height="14" />
505
+ </bpmndi:BPMNLabel>
506
+ </bpmndi:BPMNEdge>
507
+ <bpmndi:BPMNEdge id="BPMNEdge_f_ci_go" bpmnElement="f_ci_go">
508
+ <di:waypoint x="888" y="625" />
509
+ <di:waypoint x="888" y="760" />
510
+ <di:waypoint x="1038" y="760" />
511
+ <bpmndi:BPMNLabel>
512
+ <dc:Bounds x="893" y="679" width="49" height="28" />
513
+ </bpmndi:BPMNLabel>
514
+ </bpmndi:BPMNEdge>
515
+ <bpmndi:BPMNEdge id="BPMNEdge_f_reb_go" bpmnElement="f_reb_go">
516
+ <di:waypoint x="913" y="280" />
517
+ <di:waypoint x="933" y="280" />
518
+ <di:waypoint x="933" y="305" />
519
+ <di:waypoint x="1158" y="305" />
520
+ <di:waypoint x="1158" y="920" />
521
+ <di:waypoint x="1138" y="920" />
522
+ <bpmndi:BPMNLabel>
523
+ <dc:Bounds x="1101" y="310" width="49" height="28" />
524
+ </bpmndi:BPMNLabel>
525
+ </bpmndi:BPMNEdge>
526
+ <bpmndi:BPMNEdge id="BPMNEdge_f_m_gQueued" bpmnElement="f_m_gQueued">
527
+ <di:waypoint x="1088" y="145" />
528
+ <di:waypoint x="1088" y="280" />
529
+ <di:waypoint x="1245" y="280" />
530
+ <bpmndi:BPMNLabel>
531
+ <dc:Bounds x="1093" y="206" width="46" height="14" />
532
+ </bpmndi:BPMNLabel>
533
+ </bpmndi:BPMNEdge>
534
+ <bpmndi:BPMNEdge id="BPMNEdge_f_m_gBlocked" bpmnElement="f_m_gBlocked">
535
+ <di:waypoint x="1113" y="120" />
536
+ <di:waypoint x="1368" y="120" />
537
+ <di:waypoint x="1368" y="440" />
538
+ <di:waypoint x="1388" y="440" />
539
+ <bpmndi:BPMNLabel>
540
+ <dc:Bounds x="1373" y="273" width="53" height="14" />
541
+ </bpmndi:BPMNLabel>
542
+ </bpmndi:BPMNEdge>
543
+ <bpmndi:BPMNEdge id="BPMNEdge_f_ci_done" bpmnElement="f_ci_done">
544
+ <di:waypoint x="1138" y="760" />
545
+ <di:waypoint x="1238" y="760" />
546
+ </bpmndi:BPMNEdge>
547
+ <bpmndi:BPMNEdge id="BPMNEdge_f_reb_done" bpmnElement="f_reb_done">
548
+ <di:waypoint x="1138" y="940" />
549
+ <di:waypoint x="1158" y="940" />
550
+ <di:waypoint x="1158" y="965" />
551
+ <di:waypoint x="1238" y="965" />
552
+ <di:waypoint x="1263" y="965" />
553
+ <di:waypoint x="1263" y="945" />
554
+ </bpmndi:BPMNEdge>
555
+ <bpmndi:BPMNEdge id="BPMNEdge_f_m_landed" bpmnElement="f_m_landed">
556
+ <di:waypoint x="1263" y="298" />
557
+ <di:waypoint x="1263" y="318" />
558
+ <di:waypoint x="1281" y="318" />
559
+ <di:waypoint x="1281" y="540" />
560
+ <di:waypoint x="1644" y="540" />
561
+ <di:waypoint x="1644" y="180" />
562
+ <di:waypoint x="1468" y="180" />
563
+ <di:waypoint x="1468" y="160" />
564
+ </bpmndi:BPMNEdge>
565
+ <bpmndi:BPMNEdge id="BPMNEdge_f_ci_fixed" bpmnElement="f_ci_fixed">
566
+ <di:waypoint x="1263" y="785" />
567
+ <di:waypoint x="1263" y="820" />
568
+ <di:waypoint x="402" y="820" />
569
+ <di:waypoint x="402" y="160" />
570
+ <bpmndi:BPMNLabel>
571
+ <dc:Bounds x="813" y="798" width="39" height="14" />
572
+ </bpmndi:BPMNLabel>
573
+ </bpmndi:BPMNEdge>
574
+ <bpmndi:BPMNEdge id="BPMNEdge_f_reb_rebased" bpmnElement="f_reb_rebased">
575
+ <di:waypoint x="1263" y="945" />
576
+ <di:waypoint x="1263" y="980" />
577
+ <di:waypoint x="402" y="980" />
578
+ <di:waypoint x="402" y="160" />
579
+ <bpmndi:BPMNLabel>
580
+ <dc:Bounds x="806" y="958" width="53" height="14" />
581
+ </bpmndi:BPMNLabel>
582
+ </bpmndi:BPMNEdge>
583
+ </bpmndi:BPMNPlane>
584
+ </bpmndi:BPMNDiagram>
585
+ </bpmn:definitions>